zoukankan      html  css  js  c++  java
  • poj 1015

    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
    ",cnt++);
    64         printf("Best jury has value %d for prosecution and value %d for defence:
    ",(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("
    
    ");
    74     }
    75     return 0;
    76 }
  • 相关阅读:
    tips
    数学建模-预测模型优缺(搬运)
    数学建模-灰色预测模型GM(1,1)_MATLAB
    Floyd算法_MATLAB
    第二章 运算方法与运算器(浮点数的加减法,IEEE754标准32/64浮点规格化数)
    面向对象
    for循环
    if---else
    airflow的web任务管理
    airflow原理
  • 原文地址:https://www.cnblogs.com/Tree-dream/p/6680235.html
Copyright © 2011-2022 走看看