鏈接:http://poj.org/problem?id=1015
題目大意:求兩組中m個的和之後的差最小,
題目思路:動態規劃,可行方案dp(j-1, x)能演化成方案dp(j, k)的必要條件是:存在某個候選人i,i 在方案dp(j-1, x)中沒有被選上,且x+V(i) = k。在所有滿足該必要條件的dp(j-1, x)中,選出 dp(j-1, x) + S(i) 的值最大的那個,那麼方案dp(j-1, x)再加上候選人i,就演變成了方案 dp(j, k)。
題目:
Time Limit: 1000MS | Memory Limit: 65536K | |||
Total Submissions: 22306 | Accepted: 5751 | Special Judge |
Description
Based on the grades of the two parties, the judge selects the jury. In order to ensure a fair trial, the tendencies of the jury to favour either defence or prosecution should be as balanced as possible. The jury therefore has to be chosen in a way that is satisfactory to both parties.
We will now make this more precise: given a pool of n potential jurors and two values di (the defence's value) and pi (the prosecution's value) for each potential juror i, you are to select a jury of m persons. If J is a subset of {1,..., n} with m elements, then D(J ) = sum(dk) k belong to J
and P(J) = sum(pk) k belong to J are the total values of this jury for defence and prosecution.
For an optimal jury J , the value |D(J) - P(J)| must be minimal. If there are several jurys with minimal |D(J) - P(J)|, one which maximizes D(J) + P(J) should be selected since the jury should be as ideal as possible for both parties.
You are to write a program that implements this jury selection process and chooses an optimal jury given a set of candidates.
Input
These values will satisfy 1<=n<=200, 1<=m<=20 and of course m<=n. The following n lines contain the two integers pi and di for i = 1,...,n. A blank line separates each round from the next.
The file ends with a round that has n = m = 0.
Output
On the next line print the values D(J ) and P (J ) of your jury as shown below and on another line print the numbers of the m chosen candidates in ascending order. Output a blank before each individual candidate number.
Output an empty line after each test case.
Sample Input
4 2 1 2 2 3 4 1 6 2 0 0
Sample Output
Jury #1 Best jury has value 6 for prosecution and value 4 for defence: 2 3代碼:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int n,m;
int dp[25][805];
int path[25][805];
int fix=400;
int p[205],d[205];
int dis[205],sum[205];
bool select(int i,int k,int j)
{
while(path[i][k]!=-1)
{
if(path[i][k]==j)
return true;
k=k-dis[path[i][k]];
i--;
}
return false;
}
int main()
{
int cas;
cas=1;
while(scanf("%d%d",&n,&m))
{
if(n+m==0)
break;
for(int i=0;i<n;i++)
{
scanf("%d%d",&p[i],&d[i]);
dis[i]=p[i]-d[i];
sum[i]=p[i]+d[i];
}
memset(dp,-1,sizeof(dp));
memset(path,-1,sizeof(path));
fix=m*20;
dp[0][fix]=0;
for(int i=1;i<=m;i++)
{
for(int k=0;k<=2*fix;k++)
{
if(dp[i-1][k]>=0)
{
for(int j=0;j<n;j++)
{
if(!select(i-1,k,j))
{
if(dp[i][k+dis[j]]<dp[i-1][k]+sum[j])
{
dp[i][k+dis[j]]=dp[i-1][k]+sum[j];
path[i][k+dis[j]]=j;
}
}
}
}
}
}
int k=0;
for(k=0;k<=fix;k++)
{
if(dp[m][fix-k]>=0||dp[m][fix+k]>=0)
break;
}
int dd=dp[m][fix-k]>dp[m][fix+k] ? fix-k : fix+k;
int pp[205];
int tmp=dd;
for(int j=m,k=0;path[j][tmp]!=-1;k++)
{
pp[k]=path[j][tmp];
tmp=tmp-dis[pp[k]];
j--;
}
sort(pp,pp+m);
printf("Jury #%d \n",cas++);
printf("Best jury has value %d for prosecution and value %d for defence: \n",(dp[m][dd]+dd-fix)/2,(dp[m][dd]-dd+fix)/2);
for(int i=0;i<m;i++)
{
printf(" %d",pp[i]+1);
}
printf("\n");
}
return 0;
}