zoukankan      html  css  js  c++  java
  • poj1015

    题目意思:给定N对数,取期中的m对,要求取出sigma(a)与sigma(b)的差最小,如果有多种,输出两者和最大的一种。。。

    DP求解.f[i,j,k]表示前i对数中选j对,第一个数之和减第二个数之和的差为k,这种情况下第二个数之和的最大值.

    显然,f[i,j,k]=max(f[i-1,j,k],f[i-1,j-1,k-d[i]+d[i]]+p[i]);;

    View Code
     1 /*
     2  State:Accept
     3  Time:2013.2.28
     4 */
     5 
     6 #include <iostream>
     7 #include <cstdio>
     8 #include <cstdlib>
     9 #include <fstream>
    10 #include <algorithm>
    11 #include <cstring>
    12 #include <string>
    13 #include <cmath>
    14 #define minn -10000;
    15 using namespace std;
    16 int f[205][25][805] , finalx, finaly , n , m;
    17 int result[25] , d[202], p[202] , ansx, ansy , ans ,test;
    18 
    19 void init(){
    20        for (int i = 1; i <= n; ++i)
    21           scanf("%d%d",&d[i],&p[i]);
    22        memset(result, 0, sizeof(result));
    23        memset(f , 0 ,sizeof(f));
    24 }
    25      
    26 
    27 void dp(){
    28       int k2 ;
    29       for (int i = 0; i <= n; ++i)
    30          for (int j = 0; j <= m; ++j)
    31              for (int k = 0; k <= 800; ++k)     
    32                    if (j == 0 && k == 400)
    33                    f[i][j][k] = 0;
    34                       else f[i][j][k] =  minn;  
    35       
    36 
    37       for (int i = 1; i <= n; ++i)
    38          for (int j = 1; j <= min(m,i); ++j)
    39              for (int k = 0; k <= 800; ++k){
    40                   k2 = k - d[i] + p[i];   
    41                   if (k2 < 0 || k2 > 800) continue;
    42                   f[i][j][k] = max(f[i - 1][j - 1][k2] + d[i] + p[i] , f[i - 1][j][k]);
    43              }
    44       printf("Jury #%d\n", test);
    45 }
    46 
    47 void find(int i , int j , int k){
    48      if (k == 400 && j == 0) return;
    49      if (f[i][j][k] == f[i-1][j][k]) find(i - 1, j ,k);
    50      else {
    51           result[j] = i;          
    52           ansx += p[i];
    53           ansy += d[i];
    54           find(i - 1, j - 1 , k + p[i] - d[i]);
    55 
    56      }
    57 }
    58 
    59 void printans(){
    60      bool  bo = false;
    61      int temp;
    62      ans = minn;
    63      ansx = ansy = 0;
    64      for (int k = 0;  k <= 400; ++k) if (ans < 0)
    65          for (int  i = 1; i <= n; ++i)
    66            if (f[i][m][400 - k] >= 0 || f[i][m][400 + k] >= 0 ){
    67                  temp = max(f[i][m][400 - k] , f[i][m][400 + k]);
    68                  if (temp <= ans) continue;
    69                  ans = temp;
    70                  finalx = i;
    71                  finaly = 400 + k;
    72                  if (f[i][m][400 - k] > f[i][m][400 + k])
    73                    finaly = 400 -k; 
    74           }
    75      find(finalx , m , finaly); 
    76      printf("Best jury has value %d for prosecution and value %d for defence:\n",ansy, ansx);
    77      for (int i = 1 ; i <= m; ++i)  
    78                  printf("%d ",result[i]);
    79      printf("\n\n");
    80 }
    81 
    82 int main(){
    83       freopen("poj1015.in","r",stdin);
    84       freopen("poj1015.out","w",stdout);
    85       scanf("%d%d",&n , &m);
    86       while (n && m ){
    87           ++ test;
    88           init();
    89           dp();
    90           printans(); 
    91           scanf("%d%d",&n , &m);
    92           
    93       }
    94       fclose(stdin); 
    95       fclose(stdout);
    96 }

    注意最后输出,有点麻换。。

  • 相关阅读:
    cmp函数
    代码6
    代码5
    Google Code Jam在线測试题目--Alien Language
    Android ListView 和 ScrollView 冲突问题
    IOS的一个关于球碰撞的小游戏
    运用smali自己主动注入技术分析android应用程序行为
    《Pro Android Graphics》读书笔记之第二节
    单播、多播(组播)和广播的差别
    Swift闭包(Closure)
  • 原文地址:https://www.cnblogs.com/yzcstc/p/2977545.html
Copyright © 2011-2022 走看看