首页 > 代码库 > poj 1015

poj 1015

#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
using namespace std;

int n;//候选总人数
int m;//当选人数
int dp[21][801];//dp[i][j],选出i个人,这i个人的辩方和控方值的差为j
int num[21][801];//记录当选者的编号

bool select(int j,int k,int i,int *v)
{
while(j>0&&num[j][k]!=i)
{
k-=v[num[j][k]];
j--;
}
return j?false:true;
}

int main(void)
{
int time=1;
while(cin>>n>>m&&n)
{
int j,k,i;
int *p=new int[n+1];//每个人的辩方值
int *q=new int[n+1];//每个人的控方值
int *w=new int[n+1];//每个人的辩控和
int *v=new int[n+1];//每个人的辩控差
memset(dp,-1,sizeof(dp));
memset(num,0,sizeof(num));

for(i=1;i<=n;i++)
{
cin>>p[i]>>q[i];

w[i]=p[i]+q[i];
v[i]=p[i]-q[i];
}
int fix=m*20;

dp[0][fix]=0;
for(j=1;j<=m;j++)
for(k=0;k<=2*fix;k++)
{
if(dp[j-1][k]>=0)
{
for(i=1;i<=n;i++)
if(dp[j][k+v[i]] < dp[j-1][k]+w[i])
{
if(select(j-1,k,i,v))
{
dp[j][k+v[i]]=dp[j-1][k]+w[i];
num[j][k+v[i]]=i;
}
}
}
}
for(k=0;k<=fix;k++)
{
if(dp[m][fix-k]>=0||dp[m][fix+k]>=0)
break;
}
int div=dp[m][fix-k]>dp[m][fix+k]?(fix-k):(fix+k);

cout<<"Jury #"<<time++<<endl;
cout<<"Best jury has value ";
cout<<(dp[m][div]+div-fix)/2<<" for prosecution and value ";
cout<<(dp[m][div]-div+fix)/2<<" for defence:"<<endl;

int* id=new int[m];
for(i=0,j=m,k=div;i<m;i++)
{
id[i]=num[j][k];
k-=v[id[i]];
j--;
}
sort(id,id+m);//升序输出候选人编号
for(i=0;i<m;i++)
cout<<‘ ‘<<id[i];
cout<<endl<<endl;
}
return 0;
}

借鉴了一个大牛的思路,中间还是出现了很多问题,包括最后定义id[]时也没有new int ,找了半天最后才找出来。还是有很多的收获,希望有一天能够很轻松的解决dp类的问题。

poj 1015