题目链接:http://poj.org/problem?id=1015

错误解法:

网上很多解法是错误的,用dp[i][j]表示选择i个人差值为j的最优解,用path[i][j]存储路径,循环次序为“选的第几个人->选哪个人->差值之和”或者“选的第几个人->差值之和->选哪个人”,为了避免选择重复的人需要判断。错误的原因是存储路径的方式使得会覆盖一些情况,比如1 3 5和2 4 6均满足dp[3][k]最优时,若采用2 4 6作为dp[3][k]的最优解,而1 3 5 6是最终答案,那么此时6已经被dp[3][k]选择了,则得不到最终答案。

比如这组数据:

9 6
6 2
16 10
4 9
19 8
17 12
4 7
10 2
2 14
5 18
0 0
这组数据的正确答案是
Jury #1
Best jury has value 54 for prosecution and value 54 for defence:
1 2 3 4 6 9
但是错误程序的答案是
Jury #1
Best jury has value 52 for prosecution and value 52 for defence:
 1 3 4 5 6 8
但由于poj这题的数据较弱,故这种解法也可以AC,uva323那道的数据较强,就会卡这种做法,错误解的代码如下:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cmath>
 5 using namespace std;
 6 
 7 int n,m,p,d,cas=1,fix,S,A,D,P;
 8 int dp[25][900],path[25][900],sub[205],add[205],res[25];
 9 
10 bool is(int i,int j,int k){
11     while(i>0){
12         if(path[i][j]==k)
13             return false;
14         j=j-sub[path[i][j]];i=i-1;
15     }
16     return true;
17 }
18 
19 int main(){
20     while(scanf("%d%d",&n,&m)!=EOF&&n){
21         memset(dp,-1,sizeof(dp));
22         memset(path,0,sizeof(path));
23         fix=20*m;
24         dp[0][fix]=0;
25         for(int i=1;i<=n;i++){
26             scanf("%d%d",&p,&d);
27             sub[i]=p-d;
28             add[i]=p+d;
29         }
30         for(int i=0;i<m;i++)
31             for(int j=0;j<=2*fix;j++)
32                 if(dp[i][j]>=0)
33                     for(int k=1;k<=n;k++)
34                         if(is(i,j,k)&&dp[i][j]+add[k]>dp[i+1][j+sub[k]]){
35                             dp[i+1][j+sub[k]]=dp[i][j]+add[k];
36                             path[i+1][j+sub[k]]=k;
37                         }
38         int key;
39         for(key=0;key<=fix;key++)
40             if(dp[m][fix+key]>=0||dp[m][fix-key]>=0)
41                 break;
42         S=dp[m][fix+key]>dp[m][fix-key]?fix+key:fix-key;
43         A=dp[m][S];        
44         for(int i=m,j=S;i>0;){
45             res[i]=path[i][j];
46             j=j-sub[res[i]];
47             i--;
48         }
49         sort(res+1,res+m+1);
50         P=(A+(S-fix))/2;D=(A-(S-fix))/2;
51         printf("Jury #%d\n",cas++);
52         printf("Best jury has value %d for prosecution and value %d for defence:\n",P,D);
53         for(int i=1;i<=m;i++)
54             printf(" %d",res[i]);
55         printf("\n\n");
56     }
57     return 0;
58 }
View Code

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-11-22
  • 2021-08-24
  • 2021-09-30
  • 2022-12-23
  • 2021-05-29
猜你喜欢
  • 2022-12-23
  • 2021-12-18
  • 2021-07-02
  • 2021-10-09
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案