1.链接地址:
http://bailian.openjudge.cn/practice/2979
http://poj.org/problem?id=1015
2.题目:
- 总Time Limit:
- 1000ms
- Memory Limit:
- 65536kB
- Description
- 在遥远的国家佛罗布尼亚,嫌犯是否有罪,须由陪审团决定。陪审团是由法官从公众中挑选的。先随机挑选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=0
- Output
- 对每组数据,先输出一行,表示答案所属的组号,如 '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- Source
- Southwestern European Regional Contest 1996, POJ 1015, 程序设计实习2007
3.思路:
这题自己没想到思路,参照了《程序设计导引及在线实践》的思路
动态规划题目,使用深度搜索的话会超时
4.代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 6 using namespace std; 7 8 const int maxDiff = 400; 9 10 int cmp(const void* a,const void *b) 11 { 12 int int_a = *((int *)a); 13 int int_b = *((int *)b); 14 15 return int_a - int_b; 16 } 17 18 int main() 19 { 20 //freopen("C://input.txt","r",stdin); 21 22 int i,j,k; 23 int temp; 24 int temp_path,temp_diff; 25 26 int n,m; 27 cin >> n >> m; 28 29 int count = 1; 30 while(n != 0 || m != 0) 31 { 32 int *arr_sum = new int[n]; 33 int *arr_diff = new int[n]; 34 35 bool *arr_used = new bool[n]; 36 memset(arr_used,0,sizeof(bool) * n); 37 38 int int_a,int_b; 39 for(i = 0; i < n; ++i) 40 { 41 cin >> int_a >> int_b; 42 arr_sum[i] = int_a + int_b; 43 arr_diff[i] = int_a - int_b; 44 } 45 46 int **dp = new int*[m]; 47 for(i = 0; i < m; ++i) 48 { 49 dp[i] = new int[maxDiff * 2 + 1]; 50 for(j = 0; j <= maxDiff * 2; ++j) dp[i][j] = -1; 51 } 52 53 int **path = new int*[m]; 54 for(i = 0; i < m; ++i) path[i] = new int[maxDiff * 2 + 1]; 55 56 for(i = 0; i < n; ++i) 57 { 58 temp = arr_diff[i] + maxDiff; 59 if(dp[0][temp] < arr_sum[i]) 60 { 61 dp[0][temp] = arr_sum[i]; 62 path[0][temp] = i; 63 } 64 65 //cout << "dp[0][" << temp << "]=" << dp[0][temp] << "path[0][" << temp << "]=" << path[0][temp] << endl; 66 } 67 68 69 for(i = 1; i < m; ++i) 70 { 71 for(j = 0; j <= maxDiff * 2; ++j) 72 { 73 if(dp[i - 1][j] != -1) 74 { 75 76 temp_diff = j; 77 for(k = i - 1; k >= 0; --k) 78 { 79 temp_path = path[k][temp_diff]; 80 arr_used[temp_path] = true; 81 temp_diff = temp_diff - arr_diff[temp_path]; 82 } 83 84 for(k = 0; k < n; ++k) 85 { 86 if(!arr_used[k]) 87 { 88 temp = j + arr_diff[k]; 89 if(dp[i][temp] == -1 || (dp[i][temp] < dp[i - 1][j] + arr_sum[k])) 90 { 91 dp[i][temp] = dp[i - 1][j] + arr_sum[k]; 92 path[i][temp] = k; 93 } 94 } 95 } 96 97 98 temp_diff = j; 99 for(k = i - 1; k >= 0; --k) 100 { 101 temp_path = path[k][temp_diff]; 102 arr_used[temp_path] = false; 103 temp_diff = temp_diff - arr_diff[temp_path]; 104 } 105 } 106 } 107 108 } 109 110 int res_idx; 111 for(i = 0; i <= maxDiff; ++i) 112 { 113 if(dp[m - 1][maxDiff - i] != -1 || dp[m - 1][maxDiff + i] != -1) 114 { 115 if(dp[m - 1][maxDiff - i] == -1) res_idx = i; 116 else if(dp[m - 1][maxDiff + i] == -1) res_idx = - i; 117 else 118 { 119 res_idx = (dp[m - 1][maxDiff + i] > dp[m - 1][maxDiff - i] ? i : (-i)); 120 } 121 break; 122 } 123 } 124 125 cout << "Jury #" << count++ << endl; 126 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; 127 128 temp_diff = res_idx + maxDiff; 129 int *arr_res = new int[m]; 130 for(i = m - 1; i >= 0; --i) 131 { 132 temp_path = path[i][temp_diff]; 133 arr_res[i] = temp_path + 1; 134 temp_diff = temp_diff - arr_diff[temp_path]; 135 } 136 qsort(arr_res,m,sizeof(int),cmp); 137 138 for(i = 0; i < m; ++i) cout << " " << arr_res[i]; 139 cout << endl; 140 141 delete [] arr_res; 142 143 cout << endl; 144 145 delete [] arr_sum; 146 delete [] arr_diff; 147 148 for(i = 0; i < m; ++i) delete [] dp[i]; 149 delete [] dp; 150 151 152 153 for(i = 0; i < m; ++i) delete [] path[i]; 154 delete [] path; 155 156 cin >> n >> m; 157 } 158 159 return 0; 160 }