您的位置:首页 > 运维架构

OpenJudge 2979 陪审团的人选 / Poj 1015 Jury Compromise

2014-03-02 20:48 471 查看
1.链接地址:
http://bailian.openjudge.cn/practice/2979 http://poj.org/problem?id=1015
2.题目:

总Time Limit:1000msMemory Limit:65536kBDescription在遥远的国家佛罗布尼亚,嫌犯是否有罪,须由陪审团决定。陪审团是由法官从公众中挑选的。先随机挑选n个人作为陪审团的候选人,然后再从这n个人中选m人组成陪审团。选m人的办法是:


方和辩方会根据对候选人的喜欢程度,给所有候选人打分,分值从0到20。为了公平起见,法官选出陪审团的原则是:选出的m个人,必须满足辩方总分和控方总
分的差的绝对值最小。如果有多种选择方案的辩方总分和控方总分的之差的绝对值相同,那么选辩控双方总分之和最大的方案即可。Input输入包含多组数据。每组数据的第一行是两个整数n和m,n是候选人数目,m是陪审团人数。注意,1<=n<=200,
1<=m<=20 而且
m<=n。接下来的n行,每行表示一个候选人的信息,它包含2个整数,先后是控方和辩方对该候选人的打分。候选人按出现的先后从1开始编号。两组有
效数据之间以空行分隔。最后一组数据n=m=0Output对每组数据,先输出一行,表示答案所属的组号,如 'Jury #1', 'Jury #2', 等。接下来的一行要象例子那样输出陪审团的控方总分和辩方总分。再下来一行要以升序输出陪审团里每个成员的编号,两个成员编号之间用空格分隔。每组输出数据须以一个空行结束。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

SourceSouthwestern European Regional Contest 1996, POJ 1015, 程序设计实习2007

3.思路:

这题自己没想到思路,参照了《程序设计导引及在线实践》的思路

动态规划题目,使用深度搜索的话会超时

4.代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>

using namespace std;

const int maxDiff = 400;

int cmp(const void* a,const void *b)
{
int int_a = *((int *)a);
int int_b = *((int *)b);

return int_a - int_b;
}

int main()
{
//freopen("C://input.txt","r",stdin);

int i,j,k;
int temp;
int temp_path,temp_diff;

int n,m;
cin >> n >> m;

int count = 1;
while(n != 0 || m != 0)
{
int *arr_sum = new int
;
int *arr_diff = new int
;

bool *arr_used = new bool
;
memset(arr_used,0,sizeof(bool) * n);

int int_a,int_b;
for(i = 0; i < n; ++i)
{
cin >> int_a >> int_b;
arr_sum[i] = int_a + int_b;
arr_diff[i] = int_a - int_b;
}

int **dp = new int*[m];
for(i = 0; i < m; ++i)
{
dp[i] = new int[maxDiff * 2 + 1];
for(j = 0; j <= maxDiff * 2; ++j) dp[i][j] = -1;
}

int **path = new int*[m];
for(i = 0; i < m; ++i) path[i] = new int[maxDiff * 2 + 1];

for(i = 0; i < n; ++i)
{
temp = arr_diff[i] + maxDiff;
if(dp[0][temp] < arr_sum[i])
{
dp[0][temp] = arr_sum[i];
path[0][temp] = i;
}

//cout << "dp[0][" << temp << "]="  << dp[0][temp] << "path[0][" << temp << "]=" << path[0][temp] << endl;
}

for(i = 1; i < m; ++i)
{
for(j = 0; j <= maxDiff * 2; ++j)
{
if(dp[i - 1][j] != -1)
{

temp_diff = j;
for(k = i - 1; k >= 0; --k)
{
temp_path = path[k][temp_diff];
arr_used[temp_path] = true;
temp_diff = temp_diff - arr_diff[temp_path];
}

for(k = 0; k < n; ++k)
{
if(!arr_used[k])
{
temp = j + arr_diff[k];
if(dp[i][temp] == -1 || (dp[i][temp] < dp[i - 1][j] + arr_sum[k]))
{
dp[i][temp] = dp[i - 1][j] + arr_sum[k];
path[i][temp] = k;
}
}
}

temp_diff = j;
for(k = i - 1; k >= 0; --k)
{
temp_path = path[k][temp_diff];
arr_used[temp_path] = false;
temp_diff = temp_diff - arr_diff[temp_path];
}
}
}

}

int res_idx;
for(i = 0; i <= maxDiff; ++i)
{
if(dp[m - 1][maxDiff - i] != -1 || dp[m - 1][maxDiff + i] != -1)
{
if(dp[m - 1][maxDiff - i] == -1) res_idx = i;
else if(dp[m - 1][maxDiff + i] == -1) res_idx = - i;
else
{
res_idx = (dp[m - 1][maxDiff + i] > dp[m - 1][maxDiff - i] ? i : (-i));
}
break;
}
}

cout << "Jury #" << count++ << endl;
cout << "Best jury has value " << (dp[m - 1][res_idx + maxDiff] + res_idx) / 2<< " for prosecution and value " << (dp[m - 1][res_idx + maxDiff] - res_idx) / 2<< " for defence:" << endl;

temp_diff = res_idx + maxDiff;
int *arr_res = new int[m];
for(i = m - 1; i >= 0; --i)
{
temp_path = path[i][temp_diff];
arr_res[i] = temp_path + 1;
temp_diff = temp_diff - arr_diff[temp_path];
}
qsort(arr_res,m,sizeof(int),cmp);

for(i = 0; i < m; ++i) cout << " " << arr_res[i];
cout << endl;

delete [] arr_res;

cout << endl;

delete [] arr_sum;
delete [] arr_diff;

for(i = 0; i < m; ++i) delete [] dp[i];
delete [] dp;

for(i = 0; i < m; ++i) delete [] path[i];
delete [] path;

cin >> n >> m;
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: