Java实现会MLE那我也没办法了
1 //辩方总分和控方总分之差简称为“辩控差” 2 //辩方总分和控方总分之和简称为“辩控和” 3 //现用f(j, k)表示,取j 个候选人,使其辩控差为k 的所有方案中,辩控和最大的那个方案 4 //规定,如果没法选j 个人,使其辩控差为k,那么f(j, k)的值就为-1,称方案f(j, k)不可行 5 //那么,如果对k 的所有可能的取值,求出了所有的f(m, k) (-20×m≤ k ≤ 20×m),那么陪审团方案自然就很容易找到了 6 //显然,方案f(j, k)是由某个可行的方案f(j-1, x) (-20×m ≤ x ≤ 20×m)演化而来的 7 //而且,由于题目中辩控差的值k 可以为负数,而程序中数租下标不能为负数 8 //所以,在程序中不妨将辩控差的值都加上20*m,以免下标为负数导致出错
1 #include<vector> 2 #include<cstdio> 3 #include<iostream> 4 using namespace std; 5 int dp[21][801],sub[201],sum[201]; 6 vector<int> path[21][801]; 7 int main() { 8 for(int n,m,Case=0;~scanf("%d%d",&n,&m) && n && m;) { 9 for(int i=0; i<21; i++)for(int j=0; j<801; j++)path[i][j].clear();//清空vector 10 for(int i=0; i<21; i++)for(int j=0; j<801; j++)dp[i][j]=-1; 11 for(int i = 1,d,p; i <= n; i++) cin>>d>>p,sub[i] = d-p,sum[i] = d+p; 12 int ans = 20*m,x; 13 dp[0][ans] = 0; 14 int time1=0; 15 for(int k = 1; k <= n; k++)//选择一个 16 for(int i = m-1; i >= 0; i--)//进行逆推 17 for(int j = 0; j < 2*ans; j++) 18 if(dp[i][j] >= 0) { 19 if(dp[i+1][j+sub[k]] <= dp[i][j] + sum[k]) { 20 dp[i+1][j+sub[k]] = dp[i][j] + sum[k]; 21 path[i+1][j+sub[k]] = path[i][j];//每次更新都要把path全部复制过来,就是因为这个才用的vector 22 path[i+1][j+sub[k]].push_back(k); 23 } 24 } 25 for(x = 0; dp[m][ans+x] == -1 && dp[m][ans-x] == -1; x++); 26 int temp = (dp[m][ans+x] > dp[m][ans-x]) ? x : -x; 27 int sumD = (dp[m][ans+temp] + temp )/2; 28 int sumP = (dp[m][ans+temp] - temp )/2; 29 printf( "Jury #%d ",++Case); 30 printf( "Best jury has value %d for prosecution and value %d for defence: ", sumD,sumP); 31 for(int i=0; i < m; i++ )printf( " %d", path[m][ans+temp][i]); 32 printf( " " ); 33 } 34 return 0; 35 }