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

poj 1015

时间:2017-04-07 23:15:05      阅读:192      评论:0      收藏:0      [点我收藏+]

标签:for   return   不为   get   void   targe   div   printf   memset   

http://poj.org/problem?id=1015

题意:n 个人作为陪审团的候选人,然后再从这n 个人中选m 人组成陪审团,选出的m 个人,必须满足辩方总分D控方总分P的差的绝对值|D-P|最小。

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <stdlib.h>
 4 
 5 int m,n;
 6 int dp[30][805];
 7 int d[300],p[300];
 8 int path[1000][1000];
 9 int ans[30];
10 
11 int cmp(const void *a,const void *b)
12 {
13     return *(int *)a-*(int *)b;
14 }
15 
16 int main()
17 {
18     int cnt = 1;
19     while(scanf("%d%d",&n,&m),m||n)
20     {
21         for(int i = 1;i<=n;i++)
22             scanf("%d%d",&d[i],&p[i]);
23 
24         int Move = m*20;
25         memset(dp,-1,sizeof(dp));
26         memset(path,0,sizeof(path));
27 
28         dp[0][Move] = 0;
29         /**
30         DP的部分
31         dp[i][j] 代表i个候选人,相差为j的分数且和最大的那个方案
32         **/
33         for(int i = 0;i<m;i++)
34             for(int j = 0;j<=Move*2;j++)
35                 if(dp[i][j]>=0)
36                 {
37                     for(int k = 1;k<=n;k++)
38                     {
39                         if(dp[i][j]+p[k]+d[k]>dp[i+1][j+d[k]-p[k]])
40                         {
41                             int t1 = i,t2 = j;
42                             //判断是否k这个人用过了
43                             while(t1>0&&path[t1][t2]!=k)
44                             {
45                                 t2-=d[path[t1][t2]]-p[path[t1][t2]];
46                                 t1--;
47                             }
48                             if(t1==0)
49                             {
50                                 dp[i+1][j+d[k]-p[k]] = dp[i][j]+p[k]+d[k];
51                                 path[i+1][j+d[k]-p[k]] = k;
52                             }
53                         }
54                     }
55                 }
56         int tmp = Move,tmp1 = 0;
57         while(dp[m][tmp+tmp1]<0&&dp[m][tmp-tmp1]<0)  //找出那个第一个不为-1的,则说明是相差值最小的
58             tmp1++;
59         //用来找那个最小的差
60         if(dp[m][tmp+tmp1]>dp[m][tmp-tmp1])
61             tmp = tmp+tmp1;
62         else tmp = tmp-tmp1;
63          printf("Jury #%d\n",cnt++);
64         printf("Best jury has value %d for prosecution and value %d for defence:\n",(tmp-Move+dp[m][tmp])/2,(dp[m][tmp]-tmp+Move)/2);
65          for(int i=1;i<=m;i++)
66         {
67             ans[i]=path[m-i+1][tmp];
68             tmp-=d[ans[i]]-p[ans[i]];
69         }
70         qsort(ans+1,m,sizeof(int),cmp);
71         for(int i=1;i<=m;i++)
72           printf(" %d",ans[i]);
73         printf("\n\n");
74     }
75     return 0;
76 }

 

poj 1015

标签:for   return   不为   get   void   targe   div   printf   memset   

原文地址:http://www.cnblogs.com/Tree-dream/p/6680235.html

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