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 }
  • 相关阅读:
    C# 文件类的操作---删除
    C#实现Zip压缩解压实例
    UVALIVE 2431 Binary Stirling Numbers
    UVA 10570 meeting with aliens
    UVA 306 Cipher
    UVA 10994 Simple Addition
    UVA 696 How Many Knights
    UVA 10205 Stack 'em Up
    UVA 11125 Arrange Some Marbles
    UVA 10912 Simple Minded Hashing
  • 原文地址:https://www.cnblogs.com/usedrosee/p/4372361.html
Copyright © 2011-2022 走看看