zoukankan      html  css  js  c++  java
  • poj1015 Jury Compromise---背包问题变形

    题目链接:https://vjudge.net/problem/POJ-1015

    好题。首先这个状态设计的就比较巧妙:设f[i][j][k]表示前i人选j个,控方-辩方的差值为k,能得到的最大和。这儿把控方和辩方的差值作为状态的一维(可以理解成背包问题的“体积”)。

    那么就有转移方程:f[i][j][k] = max(f[i-1][j][k],f[i-1][j-1][k-(p[i]-d[i])]+p[i]+d[i])。然后注意到这个差值可能为负数,所以要把数组下标都加上400,这个在白书习题poj2184里也用到了。最后是打印方案,因为用的是三维的f[i][j][k],所以这儿方案打印就比较方便,详细见代码。应该可以省去第一维的i,但那样记录方案就有点麻(不)烦(会)

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    
    int f[210][30][810],p[210],d[210],ans[30];
    int n,m,i,j,k,ansp,ansd,res,dif,cnt,now;
    //ansp,ansd分别记录最后p方和d方的和,res记录最大和,dif是最小差值 
    
    int main(){
    	while ((scanf("%d%d",&n,&m))&&n){
    	  for (i=1;i<=n;i++) scanf("%d%d",&p[i],&d[i]);
    	  memset(f,-0x3f,sizeof(f)); 
    	  for (i=0;i<=n;i++) f[i][0][400]=0; //*初始化,注意偏移量400 
    	  for (i=1;i<=n;i++)
    	    for (j=1;j<=m;j++)
    	      for (k=0;k<=800;k++){ //*
    	      	if (i-1>=j) f[i][j][k]=f[i-1][j][k];
    	      	if (k-p[i]+d[i]>=0&&f[i-1][j-1][k-(p[i]-d[i])]>=0)
    	      	  f[i][j][k]=max(f[i][j][k],f[i-1][j-1][k-(p[i]-d[i])]+p[i]+d[i]);
    		  }
    	  i=n;j=m; res=0;dif=1e5; cnt=0;
    	  //找到最优解对应的最终状态 
    	  for (int l=0;l<=800;l++)	  
    	    if (f[n][m][l]>=0)
    	      if (abs(l-400)<dif||(abs(l-400)==dif&&res<f[n][m][l])){
    	      	k=l; dif=abs(l-400); res=f[n][m][l];
    		  }
    	  //求出一个方案 
    	  ansp=ansd=0;
    	  while (j>0){
    	  	if (f[i][j][k]==f[i-1][j][k]) i--;
    	  	else{
    	  	  ansp+=p[i]; ansd+=d[i]; ans[++cnt]=i;
    	  	  k-=(p[i]-d[i]); i--;j--; //*
    		}
    	  }
    	  printf("Jury #%d
    ",++now);
    	  printf("Best jury has value %d for prosecution and value %d for defence:
    ",ansp,ansd);
    	  for (i=cnt;i>=2;i--) printf("%d ",ans[i]);
    	  printf("%d
    
    ",ans[1]);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    SAP系统报错
    基金投资
    Reading: 重构相关
    C/C++: static variables
    C/C++: 如何删除本地文件/读取某个目录下符合某种pattern的所有文件路径
    如何在Linux下建立包含lua vm的unit test framwork
    C++实现字符串分割(类似于Python的split方法)
    postMan 汉化
    搞懂MySQL InnoDB事务ACID实现原理
    mysql 索引优化
  • 原文地址:https://www.cnblogs.com/edmunds/p/13560018.html
Copyright © 2011-2022 走看看