POJ-1015(离散化DP)
2014-06-29 22:54
239 查看
题目要求|D(J)-P(J)|最小,但|D(J)-P(J)|显然不符合最优子结构,不能直接动态规划,但题目中说要使|D(J)-P(J)|最小时的D(J)+P(J)最大化,我们知道D(J)+P(J)是符合最优子结构的,要是只用让D(J)+P(J)最大,那就是一个0-1背包问题了,想着要是能将D(J)-P(J)作为一个维度,有一定的范围,再对D(J)+P(J)动态规划的话就好了:
令f(i,j,k)表示在前i个人中选取k个人,且这k个人组成的Jury满足|D(J)-P(J)|=k,这个状态下的最大D(J)+P(J),遍历之后,再对|k| = 0~400遍历f(n,m,k),得到第一个有效的f(n,m,k)就是我们要找的k了
实现时参考了这篇文章:http://hi.baidu.com/yzwlovezxh/item/9235212c03b2dfcea5275a44
![](http://img.blog.csdn.net/20140629225249578?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdXV1b3VvdWxjeg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
令f(i,j,k)表示在前i个人中选取k个人,且这k个人组成的Jury满足|D(J)-P(J)|=k,这个状态下的最大D(J)+P(J),遍历之后,再对|k| = 0~400遍历f(n,m,k),得到第一个有效的f(n,m,k)就是我们要找的k了
实现时参考了这篇文章:http://hi.baidu.com/yzwlovezxh/item/9235212c03b2dfcea5275a44
#include <cstdio> inline int max(int a, int b){ return a > b ? a : b; } inline int min(int a, int b){ return a < b ? a : b; } int N, M; int v[201][2]; /* mirror D(J)-P(J)'s range [-400,400] to [0, 800] */ int f[21][201][400 + 400 + 1]; bool p[21][201][400 + 400 + 1]; void print(int i, int j, int k) { if(i == 0 || j == 0) return; if(p[i][j][k]){ print(i-1, j-1, k - (v[j][0] - v[j][1])); // printf("%d is choosen when we choose %d people from %d candidates with D(J)-P(J) = %d\n", // j, i, j, k - 400); printf(" %d", j); } else print(i, j-1, k); } void solve() { //initialize int mag = M * 20; for(int i = 0; i <= M; ++i) for(int j = i; j <= N; ++j) for(int k = 400 - mag; k <= 400 + mag; ++k) f[i][j][k] = -1; for(int j = 0; j <= N; ++j) f[0][j][400] = 0; //dp for(int i = 1; i <= M; ++i){//we want to choose i people jury for(int j = i; j <= N; ++j){//choose i people from first j guys int dif = v[j][0] - v[j][1];//di - pi int sum = v[j][0] + v[j][1];//di + pi int high = min(400 + mag, 400 + mag + dif); int low = max(400 - mag, 400 - mag + dif); for(int k = low; k <= high; ++k){ if(j > i){ f[i][j][k] = f[i][j-1][k];//not choose j p[i][j][k] = false; } if(f[i-1][j-1][k-dif] != -1 && f[i][j][k] < f[i-1][j-1][k-dif] + sum){//try to choose j f[i][j][k] = f[i-1][j-1][k-dif] + sum; p[i][j][k] = true; // printf("updated by f[%d][%d][%d] = %d, ", i-1, j-1, k-dif-400, f[i-1][j-1][k-dif]); } // printf("f[%d][%d][%d] = %d\n", i, j, k-400, f[i][j][k]); } } } //get path for(int d = 0; d <= mag; ++d){ // printf("f[%d][%d][%d] = %d\n", M, N, d, f [M][d]); if(f[M] [400 + d] > f[M] [400 - d]){ // printf("best jury has dif = %d, sum = %d\n", d, f[M] [400 + d]); printf("Best jury has value %d for prosecution and value %d for defence:\n", (f[M] [400 + d] - d)/2, (f[M] [400 + d] + d)/2); print(M, N, 400 + d); break; } else if(f[M] [400 - d] != -1){ // printf("best jury has dif = %d, sum = %d\n", d, f[M] [400 - d]); printf("Best jury has value %d for prosecution and value %d for defence:\n", (f[M] [400 - d] + d)/2, (f[M] [400 - d] - d)/2); print(M, N, 400 - d); break; } } } int main() { // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); int t = 0; while(scanf("%d%d", &N, &M), N || M){ ++t; printf("Jury #%d\n", t); for(int i = 1; i <= N; ++i) scanf("%d%d", &v[i][1], &v[i][0]);//pi, di solve(); puts(""); } return 0; }
相关文章推荐
- POJ 1018 Communication System(DP+离散化)
- POJ 1015 Jury Compromise【DP】
- poj 1015 dp
- poj 1015 Jury Compromise(DP)
- POJ 3666 Making the Grade 【DP+离散化】
- poj 3666 Making the Grade (有序序列,离散化dp)
- poj 1015 Jury Compromise_dp
- 【POJ 3666】Making the Grade(离散化+DP)
- poj 1015 Jury Compromise_dp
- [DP] POJ 1015
- poj 1015 DP
- DP::Poj1015 July Compromise
- POJ 1015 Jury Compromise ---- DP
- poj1015--动态规划(DP)
- [poj 3666] Making the Grade (离散化 线性dp)
- POJ1015 DP
- Hrbust 2099/Poj 1170 Shopping Offers【离散化+Dp】
- POJ 3666 Making the Grade——DP + 离散化
- [POJ 3666] Making the Grade (序列DP+离散化)
- 【CF 713C】Sonya and Problem Wihtout a Legend(离散化+dp)<POJ 3666变形>