首页 > 其他 > 详细

Jury Compromise POJ - 1015

时间:2021-03-14 23:46:14      阅读:26      评论:0      收藏:0      [点我收藏+]

原题链接

考察:01背包dp

错误思路:

       定义二维结构体结构体DP[i][j],代表前i个人选j个的值.DP[i][j].cost代表最小花费,DP[i][j].sum代表最大和.由第i个人选不选划分集合.

       此思路错在这里的最优子结构不一定推得到最优解.

比如数据:  

5 3
1 1
2 3
4 4
3 2
2 2
0 0

 

当我们枚举到f[4][3]时就出现了错误,f[4][3]的由f[3][2]和f[3][3]推来,可以发现f[3][2]取不到使f[4][3]取最优解的值.因为f[3][2]一定会取1,1与4,4.为了保存非当前最优解的子结构,需要再扩展一维.

正确思路:

       因此还需要再继续划分集合,以前i个人的累加差再划分,可以发现会出现负数,所以需要偏移.最后枚举最小差,再根据结果逆推回最初状态.

       这里如果初始化f[0][0][base*m]可能更方便一点.

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 const int N = 210,M = 21,K = 810,Base = 20;
 6 int f[N][M][K],n,m,ans[M];
 7 typedef pair<int,int> PII;
 8 PII p[N];
 9 int main()
10 {
11     int kcase = 0;
12     while(scanf("%d%d",&n,&m)!=EOF&&n)
13     {
14         memset(f,-0x3f,sizeof f);
15         f[0][0][0] = 0;
16         for(int i=1;i<=n;i++) scanf("%d%d",&p[i].first,&p[i].second);
17         if(kcase) printf("\n");
18         for(int i=1;i<=n;i++)
19           for(int j=0;j<=m&&j<=i;j++)
20            for(int k=0;k<=m*Base*2;k++) 
21            {
22                  int b = p[i].second-p[i].first+Base,v =0;
23                  f[i][j][k] = f[i-1][j][k];
24                  if(k-b<0||k-b>m*Base*2) continue;
25                  if(j>=1) f[i][j][k] = max(f[i-1][j-1][k-b]+p[i].first+p[i].second,f[i][j][k]);
26            }//ans差值最小的前提下,和最大. 
27         int base = Base*m,k = 0,res;//找最小差值 
28         while(f[n][m][base-k]<0&&f[n][m][base+k]<0) k++;
29         if(f[n][m][base-k]>f[n][m][base+k]) res = base-k;
30         else res = base+k;
31         int cnt = m,t = n,w = f[n][m][res],resf = 0,resz = 0;
32         while(cnt)
33         {
34             if(f[t-1][cnt][res]==w) t--;
35             else{
36                 w-=p[t].first+p[t].second;
37                 res-=(p[t].second-p[t].first+Base);
38                 resz+=p[t].second;//z为辩方 
39                 resf+=p[t].first;
40                 ans[cnt--] = t;
41                 t--;
42             }
43         }
44         printf("Jury #%d\n",++kcase);
45         printf("Best jury has value %d for prosecution and value %d for defence:\n",resf,resz);
46         for(int i=1;i<=m;i++)
47             printf(" %d",ans[i]);
48         printf("\n");
49     }
50     return 0;
51 }

 

Jury Compromise POJ - 1015

原文:https://www.cnblogs.com/newblg/p/14533133.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!