pku1015 Jury Compromise解题报告

该题可以转化为从一个数列中抽取一定数量的数,使其和的绝对值最小。 如:
-1,-2,-3,-4,-5,-6,-7,-8,0,1,2,3,4,5,6,7,8,9;        -400<=a<=400
从中抽取5个数,使其绝对值最小;

bool judge[21][810];//表示从数列中抽取i个数可能达到的和值。
int a[i]为数列;
第一个数时,judge[1][a[1]]=1;
第二个数时,if(judge[1][j])judge[2][j+a[2]]=1;      judge[2][a[2]]=1;
.
.
.
if(judge[i-1][j])judge[i][j+a[i]]=1;


#include<iostream>
using namespace std;

bool judge[21][810];
int path[21][810][21],path_he[21][810];
int input[201][2],m,n;

void _output(int k)
{
int i,j,add1=0,add2=0;
for(i=0;i<m;i++)
{
add1+=input[path[m][k][i]][0];
add2+=input[path[m][k][i]][1];
}
cout<<"Best jury has value "<<add1<<" for prosecution and value "<<add2<<" for defence:"<<endl;
for(i=0;i<m;i++)
cout<<' '<<path[m][k][i];
cout<<endl<<endl;
}

int main(int argc, char* argv[])
{
int jury[201],add[201];
int a=0,b,c,i,j,k,_min,_max,k1,k2;

while(cin>>n>>m)
{
if(n==0&&m==0)break;
a++;
for(i=1;i<=n;i++)
{
cin>>input[i][0]>>input[i][1];
jury[i]=input[i][0]-input[i][1];
add[i]=input[i][0]+input[i][1];
}

memset(judge,0,sizeof(judge));
memset(path_he,0,sizeof(path_he));

_min=1000;_max=-1;

//judge[1][jury[1]+400]=1;path[1][judry[1]+400][0]=1;path_he[1][jury[1]+400]=add[1];

for(i=1;i<=n;i++)
{
if(i<m)j=i;else j=m;
for(;j>=1;j--)
{
if(j==1){
b=jury[i]+400;
if(judge[1][b]==0)
{
judge[1][b]=1;path[1][b][0]=i;path_he[1][b]=add[i];
if(_min>b)_min=b;
if(_max<b)_max=b;
}
else
{
if(add[i]>path_he[1][b]){path[1][b][0]=i;path_he[1][b]=add[i];}
}
}
else
{
for(k=_min;k<=_max;k++)
{
if(judge[j-1][k])
{
b=k+jury[i];
if(judge[j][b]==0)
{
judge[j][b]=1;
for(k1=0;k1<j-1;k1++)
path[j][b][k1]=path[j-1][k][k1];
path[j][b][j-1]=i;
path_he[j][b]=path_he[j-1][k]+add[i];
if(_min>b)_min=b;
if(_max<b)_max=b;
}
else
{
if(path_he[j-1][k]+add[i]>path_he[j][b])
{
for(k1=0;k1<j-1;k1++)
path[j][b][k1]=path[j-1][k][k1];
path[j][b][j-1]=i;
path_he[j][b]=path_he[j-1][k]+add[i];
}
}
}
}
}
}
}

cout<<"Jury #"<<a<<endl;

if(judge[m][400])_output(400);
else
{
for(i=1;i<=400;i++)
{
if(judge[m][400-i]&&judge[m][400+i]){
if(path_he[m][400-i]>path_he[m][400+i])_output(400-i);
else _output(400+i);
break;
}
else if(judge[m][400+i]){_output(400+i);break;}
else if(judge[m][400-i]){_output(400-i);break;}
}
}
}
return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值