zoukankan      html  css  js  c++  java
  • 洛谷 p2066 机器分配

    这个题是我自己打出来的第二道题~(≧▽≦)/~啦啦啦,虽然想+改好像得有2小时,并且解法很不像正解。

    对于n组数据,我们发现,当前f【m】的一组可能解为w1台+w2台(w1+w2=j),此时我们并不关心w1和w2是怎么来的。

    f【m】的全部解为

    0,1,2,3....m

    m,m-1,m-2......0

    也就是说,我们只需要不停找到一个可控的f【1~m】与一组未知的数继续和出一个新的f【1~m】,直到和完全部的组。这可能就是区间dp的雏形吧。

    下面来证一下它的可行性:

    f【m】的全部解为

    0,1,2,3....m      现最优解   q1

    m,m-1,m-2......0   未求的   q2

    以m-2和2为例,q1中的2为1~求得q1这一组中,所有分配为2的最大值,那么m-2+(q1中的2)>=m-2+其它任意分配为2(1~求得q1这一组中)

    b【第几次合并】【坑位(最大可分配数量)】【组数】用来记录第几组分配了几个

    共合并n-1次,初始f[i]=a[1][i]

    没有被更新的b数组就从上一次中继承,now_i相当于w1是现最优解中的,now_j相当于w2是未知中的。

    但是,还有一个坑点:要求答案的字典序最小

    需要把第二层循环j和第三层循环k全部改为倒序,因为更改now_i值和now_j值时条件为严格大于,所以非字典序的答案即使相同也不会被记录。

    #include <iostream>
    #include <cstdio>
    using namespace std;
    
    int n,m,a[11][16],f[16],b[16][18][16];
    int now_i,now_j;
    
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++)
    			scanf("%d",&a[i][j]);
    	for(int i=1;i<=m;i++){
    		f[i]=a[1][i];
    		b[1][i][1]=i;
    	}	
    	for(int i=2;i<=n;i++){
    		for(int j=m;j>=1;j--){
    			now_i=-2,now_j=-2;
    			for(int k=j;k>=1;k--){
    				if(f[j-k]+a[i][k]>f[j]){
    					now_i=j-k;
    					now_j=k;
    					f[j]=f[j-k]+a[i][k];
    				}
    			}
    			if(now_i==-2&&now_j==-2){
    				for(int k=1;k<=i;k++)
    					b[i][j][k]=b[i-1][j][k];
    			}
    			else{
    				b[i][j][i]=now_j;
    				for(int k=1;k<i;k++)//不要把i也更新进去 
    					b[i][j][k]=b[i-1][now_i][k];
    			}
    		}
    	}
    	printf("%d
    ",f[m]);
    	for(int i=1;i<=n;i++)
    		printf("%d %d
    ",i,b[n][m][i]);
    	return 0;
    }
    

     感谢上帝~

  • 相关阅读:
    POJ 2923 Relocation (状态压缩,01背包)
    HDU 2126 Buy the souvenirs (01背包,输出方案数)
    hdu 2639 Bone Collector II (01背包,求第k优解)
    UVA 562 Dividing coins (01背包)
    POJ 3437 Tree Grafting
    Light OJ 1095 Arrange the Numbers(容斥)
    BZOJ 1560 火星藏宝图(DP)
    POJ 3675 Telescope
    POJ 2986 A Triangle and a Circle
    BZOJ 1040 骑士
  • 原文地址:https://www.cnblogs.com/jindui/p/11084791.html
Copyright © 2011-2022 走看看