zoukankan      html  css  js  c++  java
  • poj 1015 Jury Compromise(DP)

    题意:

    思路:

      1 #include<cstring>
      2 #include<iostream>
      3 #include<cmath>
      4 #include<algorithm>
      5 using namespace std;
      6 
      7 int n;  //候选人数
      8 int m;  //当选人数
      9 int dp[21][801];   //dp[j][k]:取j个候选人,使其辩控差为k的所有方案中,辩控和最大的方案的辩控和
     10 int path[21][801];  //记录所选定的候选人的编号
     11 int p[222];  //每个人的控方值
     12 int d[222];  //每个人的辩方值
     13 int s[222];  //每个人的辨控和
     14 int v[222];  //每个人的辨控差
     15 int id[222]; //保存候选人编号
     16 
     17 /*检查dp[j][k]方案是否曾选择过候选人i*/
     18 bool check(int j, int k, int i, int* v)
     19 {
     20     while (j>0 && path[j][k] != i)
     21     {
     22         k -= v[path[j][k]];
     23         j--;
     24     }
     25     return j ? false : true;
     26 }
     27 
     28 void init()
     29 {
     30     memset(dp, -1, sizeof(dp));
     31     memset(path, 0, sizeof(path));
     32     memset(p, 0, sizeof(p));
     33     memset(d, 0, sizeof(d));
     34     memset(s, 0, sizeof(s));
     35     memset(v, 0, sizeof(v));
     36 }
     37 
     38 int main()
     39 {
     40     int time = 1;
     41     while (cin >> n >> m && n)
     42     {
     43         /*Initial*/
     44         int j, k, i;
     45         init();
     46         /*Input*/
     47         for (i = 1; i <= n; i++)
     48         {
     49             cin >> p[i] >> d[i];
     50             s[i] = p[i] + d[i];
     51             v[i] = p[i] - d[i];
     52         }
     53         int fix = m * 20;  //总修正值,修正极限为从[-400,400]映射到[0,800]
     54 
     55         dp[0][fix] = 0;   //由于修正了数值,因此dp[0][fix]才是真正的dp[0][0]
     56         for (j = 1; j <= m; j++)
     57             for (k = 0; k <= 2 * fix; k++) //可能的辩控差为[0,fix*2] 
     58             {
     59                 if (dp[j - 1][k] >= 0)   //区间已平移,dp[0][fix]才是真正的dp[0][0]
     60                 {
     61                     for (i = 1; i <= n; i++)
     62                         if (dp[j][k + v[i]] < dp[j - 1][k] + s[i])
     63                         {
     64                             if (check(j - 1, k, i, v))
     65                             {
     66                                 dp[j][k + v[i]] = dp[j - 1][k] + s[i];
     67                                 path[j][k + v[i]] = i;
     68                             }
     69                         }
     70                 }
     71             }
     72 
     73 
     74         /*Output*/
     75         for (k = 0; k <= fix; k++)
     76             if (dp[m][fix - k] >= 0 || dp[m][fix + k] >= 0)    //从中间向两边搜索最小辨控差的位置k
     77                 break;
     78         int div = dp[m][fix - k] > dp[m][fix + k] ? (fix - k) : (fix + k);  //最小辨控差
     79 
     80         cout << "Jury #" << time++ << endl;
     81         cout << "Best jury has value ";
     82         //辩方总值 = (辨控和+辨控差+修正值)/2
     83         cout << (dp[m][div] + div - fix) / 2 << " for prosecution and value ";
     84         //控方总值 = (辨控和-辨控差+修正值)/2
     85         cout << (dp[m][div] - div + fix) / 2 << " for defence:" << endl;
     86 
     87         for (i = 0, j = m, k = div; i<m; i++)
     88         {
     89             id[i] = path[j][k];
     90             k -= v[id[i]];
     91             j--;
     92         }
     93         sort(id, id + m);   //升序输出候选人编号
     94         for (i = 0; i<m; i++)
     95             cout << ' ' << id[i];
     96         cout << endl << endl;
     97 
     98     }
     99     return 0;
    100 }
  • 相关阅读:
    [Swift]数学库函数math.h | math.h -- mathematical library function
    [Swift]LeetCode492. 构造矩形 | Construct the Rectangle
    FansMail:邮件发送标准API与技术实现(Java)
    FansMail:邮件发送标准API与技术实现(Java)
    大话世界格局:春秋五霸与战国七雄
    大话世界格局:春秋五霸与战国七雄
    大家好,我是FansUnion,雷文
    大家好,我是FansUnion,雷文
    2013年总结(2)-财务收入与支出
    2013年总结(2)-财务收入与支出
  • 原文地址:https://www.cnblogs.com/usedrosee/p/4372361.html
Copyright © 2011-2022 走看看