这个递归算法有什么问题?

时间:2016-06-15 14:49:30

标签: c++ algorithm sorting dynamic-programming memoization

问题陈述:

N元素置换是与集合{1,2,...,n}不同的数字的N元素序列。例如,序列2,1,4,5,3是5元素排列。 P是N元素排列。您的任务是按升序排序P.但因为它很简单,我有一条新规则。你有两个序列P和Q.P是一个N元素置换,Q最初是空的,并通过排序P形成(即最后Q = 1,2,3,...,N)。你需要实现N个步骤来排序P.在第i步中,P有N-i + 1个剩余元素,Q有i-1个元素,你必须选择一些第x个元素(来自N-i + P的1个可用元素)并将其放在Q的左侧或右侧。该步骤的成本等于x * i。总成本是各个步骤的成本之和。在N步之后,Q必须是升序。您的任务是最大限度地降低总成本。

输入

输入文件的第一行是T(T≤10),即测试用例的数量。然后是T测试案例的描述。每个测试用例的描述由两行组成。第一行包含单个整数N(1≤N≤1000)。第二行包含来自集合{1,2,...,N}的N个不同的整数,即N元素置换P。

输出

对于每个测试用例,您的程序应该写一行,包含一个整数 - 排序的最小总成本。

输入: 1 4 4 1 3 2

输出: 15

我的解决方案:

#include <iostream>
#include <map>
#include <algorithm>
using namespace std;
int sz;
int n[1001];
map<int,int>pos;
int solve(int i,int a,int b){
if(a==-1&&b==sz) //if all the elements have been moved 
    return 0;
if(i>sz)
    return INT_MAX;
    int ret = INT_MAX;
    if(a>=0) //select the element from left
        ret = min(ret,solve(i+1,a-1,b)+((i+1)*pos[n[a]]));
    if(b<sz) //select the element from right
        ret = min(ret,solve(i+1,a,b+1)+((i+1)*pos[n[b]]));
return ret;
}

int main()
{
   int t;
   cin>>t;
   while(t--){
        cin>>sz;
   for(int i=0;i<sz;i++){
    int x;
    cin>>x;
    n[i] = x; //value
    pos[x] = i+1; //position of elements of array before sorting
   }
   sort(n,n+sz); //sorting the array
   int ret = INT_MAX;
   for(int i=0;i<sz;i++)  
     ret= min(ret,solve(0,i,i+1));
             cout << ret << endl;

        }
    return 0;
}

这会返回错误的答案。我的方法有什么问题?怎么解决这个问题?

1 个答案:

答案 0 :(得分:0)

一个问题是您正在根据pos [n [a]]计算成本。

pos [n [a]]返回原始数组中的位置,但成本应该基于当前数组P中的位置(即某些元素移动到Q)。

例如,如果P最初是{4,1,2},那么2的位置是x == 3,但是在P减小到{1,2}之后,那么2的位置是x = = 2。