zoukankan      html  css  js  c++  java
  • POJ1015-Jury Compromise-dp

    略复杂的dp题。

    有n个人,每个人有两个分数di,pi。从中选出m个人,要求|sigma(di)-sigma(pi)|最小,相同时则输出sigma(di)+sigma(pi)最大的情况。

    答案完整输出方案。

    dp[i][j]表示i个人的组合里,差值为j的情况下,和值的最大值。

    计算每一个人的差值subi,和值sumi

    则dp[i][j] = max(dp[i-1][j-subk]+sumk) k∈n

    注意dp的时候为了能表示负数,要加一个修正值。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 
     5 using namespace std;
     6 
     7 const int maxn = 200+10;
     8 const int X = 500;
     9 const int INF = 0x3f3f3f3f;
    10 
    11 int n,m;
    12 int sum[maxn],sub[maxn];
    13 int dp[25][10*maxn];
    14 int path[25][10*maxn];
    15 
    16 bool check(int i,int j,int k)
    17 {
    18     int tmp ;
    19     while(path[i][X+j])
    20     {
    21         tmp = path[i][X+j];
    22         if(k == tmp)
    23             return false;
    24         j -= sub[tmp];
    25         i--;
    26     }
    27     return true;
    28 }
    29 
    30 int main()
    31 {
    32     int cas = 0;
    33     while(scanf("%d%d",&n,&m) && n)
    34     {
    35         int d,p;
    36         cas++;
    37         for(int i=1;i<=n;i++)
    38         {
    39             scanf("%d%d",&p,&d);
    40             sum[i] = p+d;
    41             sub[i] = p-d;
    42         }
    43         memset(dp,-1,sizeof dp);
    44         memset(path,0,sizeof path);
    45 
    46         dp[0][X+0] = 0;
    47 
    48         int ans_sub = 400+5;
    49         for(int i=1;i<=m;i++)
    50         {
    51             for(int j=-400;j<=400;j++)
    52             {
    53                 for(int k=1;k<=n;k++)if(dp[i-1][X+j-sub[k]] != -1 && check(i-1,j-sub[k],k))
    54                 {
    55                     if(dp[i-1][X+j-sub[k]]+sum[k] > dp[i][X+j])
    56                     {
    57                         dp[i][X+j] = dp[i-1][X+j-sub[k]]+sum[k];
    58                         path[i][X+j] = k;
    59                         //printf("i:%d j:%d k:%d dp:%d
    ",i,j,k,dp[i][X+j]);
    60                         if(i==m && ( abs(j) < abs(ans_sub) || (abs(j)==abs(ans_sub) && dp[i][X+j] > dp[i][X+ans_sub]) ) )
    61                         {
    62                             ans_sub = j;
    63                         }
    64                     }
    65                 }
    66             }
    67         }
    68 
    69         //printf("%d
    ",ans_sub);
    70         printf("Jury #%d
    ",cas);
    71         printf("Best jury has value %d for prosecution and value %d for defence: 
    ",(dp[m][X+ans_sub]+ans_sub)/2,(dp[m][X+ans_sub]-ans_sub)/2);
    72 
    73         int ans[25],cnt=0;
    74         for(int i=m;i>=1;i--)
    75         {
    76             ans[cnt++] = path[i][X+ans_sub];
    77             ans_sub -= sub[ans[cnt-1]];
    78         }
    79         sort(ans,ans+cnt);
    80 
    81         for(int i=0;i<cnt;i++)
    82         {
    83             printf(" %d",ans[i]);
    84         }
    85         printf("
    
    ");
    86     }
    87 }

    最近dp写的略顺手

  • 相关阅读:
    数据结构——线性结构(链表)
    栈和队列的应用——迷宫问题(深度、广度优先搜索)
    数据结构——线性结构(列表、栈、队列)
    hibernate之HQL
    hibernate关联关系(多对多)
    Hibernate关联关系(一对多)
    hibernate之主键生成策略
    hibernate入门
    reduce个数问题
    hbase连接linux开发过程
  • 原文地址:https://www.cnblogs.com/helica/p/5538012.html
Copyright © 2011-2022 走看看