您的位置:首页 > 其它

1015 Jury Compromise 解题报告

2009-02-07 11:50 274 查看
做了很久,终于把这道在书上看过的题写出来了。虽然方法笨了点,但毕竟是自己写的,还是把它贴出来,见笑了。

Memory: 8428K

Time: 63MS
Language: G++

Result: Accepted

Faults: 6 wa+ 3 MLE

#include <iostream>
using namespace std;
#define M 21
#define N 210
#define us unsigned short
int diff
,sum
;
int dp[M][810];
//用来储存路径path[i][j][k]代表选i个人总和为j,差和为k所选的人的编号
//这套储存方式使得path只能用unsigned short了
us path[M][810][810];
int ttime(1);
void print(int m,int x)
{
us top(0),queue[21];
int s(dp[m][x]);
int a((s+x-400)/2),b(dp[m][x]-a);
printf("Jury #%d/n",ttime++);
printf("Best jury has value %d for prosecution and value %d for defence:/n",a,b);
while(m>0)	{
queue[top++]=path[m][s][x];
int tmp=s-sum[path[m][s][x]];
x-=diff[path[m][s][x]];
s=tmp;
m--;
}
while(top--)
cout << queue[top]<< " " ;
cout << endl << endl;
}
int main()
{
int n,m;
int a,b;
while(cin >> n >> m && n)
{
memset(dp,-1,sizeof(dp));
dp[0][400]=0;
for(int i = 1; i <= n; i++)	{
cin >> a >> b;
diff[i] = a-b;
sum[i]= a+b;
for(int j = min(i,m)-1; true; j--)	{
for(int k = 0; k < 801; k++)
//如果选j个人能得到差和为k,而且又是最优的
if(dp[j][k]>=0 && dp[j+1][k+diff[i]]<(dp[j][k]+sum[i]))	{
dp[j+1][k+diff[i]] = dp[j][k]+sum[i];
path[j+1][dp[j+1][k+diff[i]]][k+diff[i]] = i;
}
if(!j)
break;
}
}
//找差和最小的
for(int i = 0; i <= 400; i++)	{
if(dp[m][400-i]>=0&&dp[m][400-i]>=dp[m][400+i])	{
print(m,400-i);
break;
}
if(dp[m][400+i]>=0&&dp[m][400-i]<dp[m][400+i])	{
print(m,400+i);
break;
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: