Algorithm 如何使序列成为具有最少步数的非递减序列?
以下是 给定一个由N个整数组成的序列。在每个步骤中,允许将任何数字的值增加1或减少1。游戏的目标是使序列以最少的步数不递减 例如,给定 3 2-1 2 11 可以将此序列设置为4个步骤中的非递减序列(减少3乘以1,增加-1乘以3) 序列将变为Algorithm 如何使序列成为具有最少步数的非递减序列?,algorithm,sorting,dynamic-programming,Algorithm,Sorting,Dynamic Programming,以下是 给定一个由N个整数组成的序列。在每个步骤中,允许将任何数字的值增加1或减少1。游戏的目标是使序列以最少的步数不递减 例如,给定 3 2-1 2 11 可以将此序列设置为4个步骤中的非递减序列(减少3乘以1,增加-1乘以3) 序列将变为 2 2 2 2 11 我该如何解决这个问题呢?问题表明,您应该尽量减少更改次数。 假设最后一个数字是-1000000。 如果您按顺序运行序列,您将不得不向最后一个元素添加1000002以获得非递减序列,但解决方案将无法满足使用最小步数的要求。 因此,最好
2 2 2 2 11
我该如何解决这个问题呢?问题表明,您应该尽量减少更改次数。 假设最后一个数字是-1000000。 如果您按顺序运行序列,您将不得不向最后一个元素添加1000002以获得非递减序列,但解决方案将无法满足使用最小步数的要求。
因此,最好在序列中运行一次,记录元素之间的差异。希望你明白我的意思。(我的书面表达没有自己想象的那么清晰:-)我已经用C#提供了工作代码。它可以很容易地移植到您选择的语言。时间复杂度约为n2。如果count大于minimumValue,则可以在方法GenerateSequenceForveyIndex()中对其进行优化
使用系统;
使用System.Collections.Generic;
命名空间控制台应用程序2
{
班级计划
{
静态void Main(字符串[]参数)
{
Sequence seq=新序列();
seq.generateSequenceForveyIndex();
Console.ReadLine();
}
}
类序列
{
整数计数;
公共序列()
{
//获取输入的数量
Console.WriteLine(“值的数量?”);
this.count=int.Parse(Console.ReadLine());
Console.WriteLine(“输入值,然后返回/输入”);
GetInputSequence();
}
List inputSequence=新列表();
私有void GetInputSequence()
{
for(int index=0;indexnewValue)minimumValue=newValue;
Console.WriteLine(“移动次数:+newValue”);
Console.WriteLine();
}
Console.WriteLine(“最小移动次数:+minimumValue”);
}
专用整数生成顺序循环索引(整数索引)
{
int numberOfMoves=0;
int[]newOutputSequence=newint[count];
int[]差异顺序=新的int[计数];
this.inputSequence.CopyTo(newOutputSequence);
对于(int ind=0;indindex&&differenceSequence[ind]<0)继续;
numberOfMoves+=Math.Abs(差分顺序[ind]);
newOutputSequence[ind]+=差分序列[ind];
}
显示序列(差异序列,“差异序列:”);
显示序列(newOutputSequence,“新序列:”);
返回移动次数;
}
私有静态void DisplaySequence(int[]newOutputSequence,字符串标题)
{
控制台。写入(标题);
for(int i=0;i
算法说明 每个元素值都可以作为轴心值,这意味着其左侧的值应等于其自身的值,右侧的值应大于或等于其自身的值。 已经说过,最多可以有“n”个唯一的非降序序列。 现在,算法获取每个值(请参见方法GenerateSequenceForveyIndex)并生成新的非降序序列 在GenerateSequenceForCurrentIndex()中,确保索引左侧的值等于数组[index]。我们不必担心小于,因为这将由不同的序列处理(当索引<当前索引时)。确保右侧的值大于或等于当前值。任何差异都被视为附加移动(绝对值) 最后,DisplaySequence()只是显示序列中的值。
\include
#include <stdio.h>
#include <stdlib.h>
int get_destination( int numbers[], int size ) {
int i,j;
int destination = 0;
int swap_done = 0;
for ( i = 0; i < size - 1; i++) {
for (j = 0; j < size - 1; j++) {
if ( numbers[j] > numbers[j + 1]){
destination = j + 1;
swap_done = 1;
}
}
if ( swap_done ) {
break;
}
}
return destination;
}
int main( int argc, char **argv ) {
#define SIZE 5
//int numbers[SIZE]= {3, 2, -1, 2, 11};
//int numbers[SIZE]= {1,2,3,4,5};
int numbers[SIZE]= {2, 1, 1, 1, 1};
int answer = 0;
int dest = get_destination( numbers, SIZE);
if ( dest ) {
for ( int i = 0; i < SIZE - 1; i++) {
answer = answer + abs( abs(numbers[i]) - abs(numbers[dest]));
}
}
printf ( "ANSWER = %d\n", answer );
return 0;
}
#包括
int get_目的地(整数编号[],整数大小){
int i,j;
int destination=0;
int swap_done=0;
对于(i=0;i数字[j+1]){
目的地=j+1;
交换完成=1;
}
}
如果(交换完成){
打破
}
}
返回目的地;
}
int main(int argc,字符**argv){
#定义尺寸5
//整数[大小]={3,2,-1,2,11};
//整数[大小]={1,2,3,4,5};
整数[大小]={2,1,1,1,1};
int-answer=0;
int dest=获取目的地(数字、大小);
如果(目的地){
对于(int i=0;iusing System;
using System.Collections.Generic;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
Sequence seq = new Sequence();
seq.GenerateSequenceForEveryIndex();
Console.ReadLine();
}
}
class Sequence
{
int count;
public Sequence()
{
// Get Number of inputs
Console.WriteLine("Number of values? ");
this.count = int.Parse(Console.ReadLine());
Console.WriteLine("Enter input values followed by RETURN/ENTER");
GetInputSequence();
}
List<int> inputSequence = new List<int>();
private void GetInputSequence()
{
for (int index = 0; index < count; index++)
inputSequence.Add(int.Parse(Console.ReadLine()));
}
internal void GenerateSequenceForEveryIndex()
{
int minimumValue = 0;
for (int index = 0; index < count; index++)
{
// Get output sequence for every index
// You can make a decision to get the minimum of the moves
int newValue = GenerateSequenceForCurrentIndex(index);
if (minimumValue == 0 || minimumValue > newValue) minimumValue = newValue;
Console.WriteLine("Number of moves: " + newValue);
Console.WriteLine();
}
Console.WriteLine("Minimum number of moves: " + minimumValue);
}
private int GenerateSequenceForCurrentIndex(int index)
{
int numberOfMoves = 0;
int[] newOutputSequence = new int[count];
int[] differenceSequence = new int[count];
this.inputSequence.CopyTo(newOutputSequence);
for (int ind = 0; ind < count; ind++)
{
if (ind == index) continue;
differenceSequence[ind] = (ind == 0 ? newOutputSequence[index] : newOutputSequence[ind - 1])
- newOutputSequence[ind];
// If sorted as non-decreasing, continue
if (ind > index && differenceSequence[ind] < 0) continue;
numberOfMoves += Math.Abs(differenceSequence[ind]);
newOutputSequence[ind] += differenceSequence[ind];
}
DisplaySequence(differenceSequence, "Diff Sequence: ");
DisplaySequence(newOutputSequence, "New Sequence: ");
return numberOfMoves;
}
private static void DisplaySequence(int[] newOutputSequence, string heading)
{
Console.Write(heading);
for (int i = 0; i < newOutputSequence.Length; i++)
Console.Write(newOutputSequence[i] + " ");
Console.WriteLine();
}
}
}
#include <stdio.h>
#include <stdlib.h>
int get_destination( int numbers[], int size ) {
int i,j;
int destination = 0;
int swap_done = 0;
for ( i = 0; i < size - 1; i++) {
for (j = 0; j < size - 1; j++) {
if ( numbers[j] > numbers[j + 1]){
destination = j + 1;
swap_done = 1;
}
}
if ( swap_done ) {
break;
}
}
return destination;
}
int main( int argc, char **argv ) {
#define SIZE 5
//int numbers[SIZE]= {3, 2, -1, 2, 11};
//int numbers[SIZE]= {1,2,3,4,5};
int numbers[SIZE]= {2, 1, 1, 1, 1};
int answer = 0;
int dest = get_destination( numbers, SIZE);
if ( dest ) {
for ( int i = 0; i < SIZE - 1; i++) {
answer = answer + abs( abs(numbers[i]) - abs(numbers[dest]));
}
}
printf ( "ANSWER = %d\n", answer );
return 0;
}
{2} {-1 2 11} --> {2} {2 2 11}
{2} {-1 0 1} --> {2} {2 2 2}
{3} {2} --> {2} {2}
{2 3} {1} --> {1 1} {1}
{3} {2} {-1 2 11}
adjust left group --> {2 2} {-1 2 11}
adjust left group --> {-1 -1 -1 2 11}
{-1 -1 -1 2 11} (adjust left, adjust left) --> score 7
{ 2 2 2 2 11} (adjust left, adjust right) --> score 4 (best)
{-1 -1 -1 2 11} (adjust right, adjust left) --> score 7
{ 3 3 3 3 11} (adjust right, adjust right) --> score 6
f(1,1)=|a1-b1|
f(1,j)=min{|a1-bj|,f(1,j-1)}, j>1
f(i,1)=|ai-b1|+f(i-1,1), i>1
f(i,j)=min{f(i,j-1),f(i-1,j)+|ai-bj|}, i>1, j>1