POJ 1015 Jury Compromise
动态规划的综合题。绝对经典的好题目。
整整做了五个小时,但是由于自己思维不严谨,太急躁,静不下心来。导致写完程序后煎熬了2个小时。
得不偿失,以后写程序的时候不要再听歌。
AC后没有快感,因为头脑始终没清醒过。
View Code
1 //陪审团的人选,选出的M个人必须满足辩方总分和控方总分差的绝对值最小。如果差的绝对值一样,那么选择双方总分之和最大的方案。
2 //需要用一个数据结构存储辩控差一定时最大的辩控和。用二维数组jury[i][j]表示i个人辩控差为j的时候的最大的辩控和。j先加个400.
3 //jury[0][0]=0,第一个人的时候,构造出jury[1][p[i]],此时,设置path[1][p[i]]=i。
4 //到加第二个人的时候,遍历N个人,可以求出jury[2][p[i]+p[j]],此时path[2][p[i]+p[j]]=j。注意,这个时候要注意往回遍历path数组,检测要加的人是否已经出现。
5
6
7 #include<iostream>
8 #include<memory.h>
9 #include<stdlib.h>
10
11 using namespace std;
12
13 int CompareInt(const void *e1,const void *e2)
14 {
15 return *((int *)e1)-*((int *)e2);
16 }
17
18 int main()
19 {
20 int n,m;
21 int d[201],p[201];
22 int jury[21][801],path[21][801];
23 cin>>n>>m;
24 int cases=1;
25 while(m+n)
26 {
27 for(int i=1;i<=n;i++)
28 {
29 int dk,pk;
30 cin>>dk>>pk;
31 d[i]=dk+pk;
32 p[i]=dk-pk;
33 }
34 memset(jury,-1,sizeof(jury)); //注意这个函数的写法。
35 memset(path,0,sizeof(path));
36 int initM=m*20;
37 jury[0][initM]=0;
38 d[0]=0;
39 p[0]=0;
40 for(int j=0;j<m;j++)//选m个人
41 {
42 for(int i=1;i<=n;i++)
43 {
44 for(int k=0;k<=40*m;k++)
45 {
46 if(jury[j][k]!=-1&&jury[j][k]+d[i]>jury[j+1][k+p[i]])
47 {
48 int t1=j,t2=k;
49 while(t1>0&&path[t1][t2]!=i)
50 {
51 t2-=p[path[t1][t2]];
52 t1--;
53 }
54 if(t1==0)
55 {
56 jury[j+1][k+p[i]]=jury[j][k]+d[i];
57 path[j+1][k+p[i]]=i;
58 // cout<<j+1<<" "<<k+p[i]-initM<<" "<<i<<endl;
59 }
60 }
61
62 }
63 }
64
65 }
66 int t3=initM;
67 int t4=0;
68 int t5;
69 while(jury[m][t3+t4]<0&&jury[m][t3-t4]<0)//注意这种艺术性的处理,本来要两个变量,现在集中一个变量t4中。
70 t4++;
71 if(jury[m][t3+t4]>jury[m][t3-t4])
72 t5=t3+t4;
73 else
74 t5=t3-t4;
75
76 cout<<"Jury "<<"#"<<cases<<endl;
77 cases++;
78 int prosecution=(jury[m][t5]+t5-initM)/2,defence=(jury[m][t5]-t5+initM)/2;
79 cout<<"Best jury has value "<<prosecution<<" for prosecution and value "<<defence<<" for defence:"<<endl;
80 int answer[21];
81 for(int i=1;i<=m;i++)
82 {
83 answer[i]=path[m+1-i][t5];
84 t5-=p[answer[i]];
85 }
86 qsort(answer+1,m,sizeof(int),CompareInt);
87 for(int i=1;i<=m;i++)
88 cout<<" "<<answer[i];
89 cout<<endl;
90 cout<<endl;
91 cin>>n>>m;
92 }
93 return 0;
94
95 }