POJ 2979 陪审团的人选 解题报告
POJ 2979 陪审团的人选 解题报告
编号:2979
考查点:动态规划
思路:我感觉这是书上最难的一道题,解题思路看了好几遍才明白,然后又找了好几份相关代码研究了半天,终于出来了我这个代码.。
提交情况:用了好几个小时,修正了大bug、小bug多个后,终于AC.>
Source Code:
//POJ Grids 2979
#include <iostream>
using namespace std;
int V[210];
int S[210];
int an[21];
int f[21][810];
int path[21][810];
int Compare(const void* e1,const void* e2)
{
return *((int*)e1) - *((int*)e2);
}
int main()
{
int n,m,count=0;
while (cin>>n>>m&&m+n)
{
count++;
for (int i=1;i<=n;i++)
{
int a,b;
cin>>a>>b;
V[i] = a-b;
S[i] = a+b;
}
memset(f,-1,sizeof f);
memset(path,0,sizeof path);
int zero = m*20;
f[0][zero] = 0;
for (int i=0;i<m;i++)
{
for (int k=0;k<=zero*2;k++)
{
if (f[i][k]>=0)
{
for (int j=1;j<=n;j++)
{
if (f[i][k]+S[j]>f[i+1][k+V[j]])
{
int index = i,temp = k;
while (index)
{
if (path[index][temp]==j)
break;
temp -= V[path[index--][temp]];
}
if (index==0)
{
f[i+1][k+V[j]] = f[i][k]+S[j];
path[i+1][k+V[j]] = j;
}
}
}
}
}
}
int k = 0;
for (int i=0;i<=zero;i++)
{
if (f[m][zero-i]!=-1||f[m][zero+i]!=-1)
{
k = f[m][zero-i]>f[m][zero+i] ? zero-i : zero+i;
break;
}
}
int a = (f[m][k]+k-zero)/2;
int b = (f[m][k]-k+zero)/2;
cout<<"Jury #"<<count<<endl;
cout<<"Best jury has value "<<a<<" for prosecution and value "<<b<<" for defence:"<<endl;
for (int i=0;i<m;i++)
{
an[i] = path[m-i][k];
k -= V[an[i]];
}
qsort(an,m,sizeof(int),Compare);
for (int i=0;i<m;i++)
cout<<an[i]<<" ";
cout<<endl<<endl;
}
return 0;
}
总结:这道题也是书上的最后一道题了,算是画了半个句号。剩下的习题我还要继续努力!
By Ns517
Time 09.02.10