码迷,mamicode.com
首页 > 其他好文 > 详细

Poj 1015

时间:2017-04-14 19:50:45      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:space   str   下标   键盘   sum   地方   i++   --   最小   

传送门:http://poj.org/problem?id=1015

大概就是有m个人,每个人有一个d值一个p值,从m个人中选出n个人,使得他们的d值和与p值和之差的绝对值最小,若有多个答案两数之差相同选其中d值和与p值和最大的。

也是背包问题。二维数组,dp[i][j],取i个人,差值为j,和放在dp[i][j]中,path[i][j]记录路径。

由于下标没有负数,将整个数组向右移动400(20*20)个单位。400为差值为0的地方。

//整理好思路再进行编程真的会更高效——来自一个没有事先思考好就敲键盘结果最后改了老半天程序的渣渣

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 using namespace std; 
 5 int main(){
 6     int n,m;
 7     int dp[21][801];
 8     int d[200];
 9     int p[200];
10     int path[21][801];
11     int Jury[20];
12     int k=1;
13     while(cin>>n>>m){
14         if(n==0&&m==0){
15             break;
16         }
17         for(int i=0;i<n;i++){
18             cin>>d[i]>>p[i];
19         }
20         int SD=20;
21         memset(dp,-1,sizeof(dp));
22         dp[0][400]=0;
23         memset(path,-1,sizeof(path));
24         for(int i=1;i<=m;i++){
25             for(int j=400-SD*(i-1);j<=400+SD*(i-1);j++){
26                 if(dp[i-1][j]>=0){
27                     for(int t=0;t<n;t++){
28                         int T2;
29                         int T3=j;
30                         bool flag=true;
31                         for(int T1=i-1;T1>0;T1--){
32                             T2=path[T1][T3];
33                             if(T2==t){
34                                 flag=false;
35                                 break;    
36                             }
37                             T3=T3-(d[T2]-p[T2]);
38                         }
39                         if(flag&&((dp[i-1][j]+d[t]+p[t])>dp[i][j+d[t]-p[t]])){
40                             dp[i][j+d[t]-p[t]]=dp[i-1][j]+d[t]+p[t];
41                             path[i][j+d[t]-p[t]]=t;
42                         }
43                     }
44                 }
45             }
46         }
47         int biaozhi;
48         for(int cha=0;cha<=SD*m;cha++){
49             if(dp[m][400+cha]>=0||dp[m][400-cha]>=0){
50                 biaozhi=dp[m][400+cha]>dp[m][400-cha]?400+cha:400-cha;
51                 break;
52             }
53         }
54         int T2;
55         for(int T1=m;T1>0;T1--){
56             T2=path[T1][biaozhi];
57             Jury[T1-1]=T2;
58             biaozhi=biaozhi-(d[T2]-p[T2]);
59         }
60         sort(Jury,Jury+m);
61         int sumD=0;
62         int sumP=0;
63         for(int i=0;i<m;i++){
64             sumD+=d[Jury[i]];
65             sumP+=p[Jury[i]];
66         }
67         cout<<"Jury #"<<k<<endl;
68         cout<<"Best jury has value "<<sumD<<" for prosecution and value "<<sumP<<" for defence: "<<endl;
69         for(int i=0;i<m;i++){
70             cout<< <<Jury[i]+1;
71         }
72         cout<<endl;
73         k++;
74     }
75 }

 

Poj 1015

标签:space   str   下标   键盘   sum   地方   i++   --   最小   

原文地址:http://www.cnblogs.com/marlenemizuno/p/6710293.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!