北大ACM(POJ1015-Jury Compromise)

本文详细解析了POJ 1015问题的动态规划解法,通过C++代码实现,展示了如何利用二维数组dp进行状态转移,以及如何回溯最优路径。适用于对动态规划算法感兴趣的读者。
Question:http://poj.org/problem?id=1015
问题点:DP。
 1 Memory: 1352K        Time: 94MS
 2 Language: C++        Result: Accepted
 3 
 4 #include <iostream>
 5 #include <vector>
 6 using namespace std;
 7 #define MAX_JURY 201
 8 #define MAX_CHOICE 21  //人员编号从1开始
 9 int dp[21][840];//21是人  840是辩控差   值是辩控和
10 vector<int> path[21][840];//值是最后一条路径
11 struct jury{
12     int minus;//辩控差
13     int sum;//辩控和
14 };
15 int main()
16 {
17     int total,choice,zero;
18     jury pool[MAX_JURY];
19     int eg = 1;
20     while(cin>>total>>choice && (total>0 && choice>0))
21     {
22         zero = 20*choice;//实际零点值
23         memset(pool,0,total);
24         for(int i=1,pi,di;i<=total;i++)
25         {
26             cin>>pi>>di;
27             pool[i].minus = di - pi;
28             pool[i].sum = di + pi;
29         }
30         memset(dp,-1,sizeof(dp));
31         for(int i=0;i<21;i++)
32             for(int j=0;j<840;j++)
33                 path[i][j].clear();
34 
35         dp[0][zero] = 0;
36         for(int k=1;k<=total;k++)
37         {
38             for(int i=choice;i>0;i--)//更新路径先长后短,避免交叉覆盖
39             {
40                 for(int j=0;j<=2*zero;j++)
41                 {
42                     if(dp[i-1][j]>=0)
43                     {
44                         if(dp[i][j+pool[k].minus] < dp[i-1][j] + pool[k].sum)
45                         {
46                             dp[i][j+pool[k].minus] = dp[i-1][j] + pool[k].sum;
47                             path[i][j+pool[k].minus] = path[i-1][j];
48                             path[i][j+pool[k].minus].push_back(k);
49                         }
50                     }
51                 }
52             }
53         }
54         int idx;
55         for(idx=0;dp[choice][zero-idx]==-1 && dp[choice][zero+idx]==-1;idx++);
56         int v = dp[choice][zero-idx]>dp[choice][zero+idx]?-idx:idx;
57         idx = zero + v;
58         cout << "Jury #" << eg++ <<endl;
59         cout << "Best jury has value "<<(dp[choice][idx]-v)/2<<" for prosecution and value "<<(dp[choice][idx]+v)/2<<" for defence:"<<endl;
60 
61         for(int l=0;l<choice;l++)
62         {
63             cout << " "<< path[choice][idx][l] ;
64         }
65         cout<<endl;
66     }
67   return 0;
68 }

 

转载于:https://www.cnblogs.com/TYcnblogs/p/poj1015.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值