zoukankan      html  css  js  c++  java
  • bzoj1190 梦幻岛宝珠

    题目链接:https://darkbzoj.tk/problem/1190

    显然不可能直接0/1背包
    考虑(wei = a * 2 ^ b)这个性质,于是可以按(b)分层转移,
    (f[i][j])表示只用(wei = a * 2 ^ i)的物品拼成重量为(j * 2 ^ i)的最大价值
    (f[i][j])即为普通的0/1背包
    考虑分层转移
    (g[i][j])表示只用(wei = a * 2 ^ k,(k = 1,2,ldots,i))的物品拼成重量为(j * 2 ^ i + (w的后i-1位))的最大价值
    (g[i][j])的转移方程为

    [g[i][j] = max(f[i][j-k] + g[i-1][min(1000,g[i-1][k*2 + w_{i-1}]),(k = 0,1,ldots,j) ]

    最终的答案即为(g[len][1])

    遗留问题:0/1背包,完全背包等的初值问题

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<cmath>
    #include<stack>
    #include<queue>
    using namespace std;
    typedef long long ll;
    
    const int maxn = 110;
    
    int n,m,cnt;
    ll v[maxn],w[maxn],c[maxn],vb[maxn][maxn],f[maxn][maxn*100],g[maxn][maxn*100];
    int wb[maxn][maxn];
    
    ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f; }
    
    int main(){
    	while(1){
    		memset(c,0,sizeof(c));
    		memset(f,0,sizeof(f));
    		memset(g,0,sizeof(g)); 
    		 
    		n = read(), m = read(); cnt = 0;
    		if(n==-1 && m==-1) break;
    		
    		for(int i=1;i<=n;++i) w[i] = read(), v[i] = read();
    		
    		int W = m, num;
    		while(W > 0){ ++cnt; W >>= 1; }
    		
    		for(int i=1;i<=n;++i){
    			W = w[i], num = 0;
    			while(W % 2 == 0){ ++num; W /= 2; }
    			wb[num][++c[num]] = W, vb[num][c[num]] = v[i];
    		}
    		
    		for(int i=0;i<cnt;++i){
    			f[i][0] = 0;
    			for(int I=1;I<=c[i];++I){
    				for(int j=1000;j>=wb[i][I];--j){
    					if(f[i][j-wb[i][I]] != -1) f[i][j] = max(f[i][j], f[i][j-wb[i][I]] + vb[i][I]);
    				}
    			}
    		}
    		
    		for(int j=0;j<=1000;++j) g[0][j] = f[0][j];
    		for(int i=1;i<cnt;++i){
    			for(int j=0;j<=1000;++j){
    				for(int k=0;k<=j;++k){
    					if(((k<<1) + ((m>>(i-1)) & 1)) <= 1000) g[i][j] = max(g[i][j], f[i][j-k] + g[i-1][(k<<1) + ((m>>(i-1)) & 1)]);
    				}
    			}
    		}
    		
    		printf("%lld
    ",g[cnt-1][1]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    UVa 1349 (二分图最小权完美匹配) Optimal Bus Route Design
    UVa 1658 (拆点法 最小费用流) Admiral
    UVa 11082 (网络流建模) Matrix Decompressing
    UVa 753 (二分图最大匹配) A Plug for UNIX
    UVa 1451 (数形结合 单调栈) Average
    UVa 1471 (LIS变形) Defense Lines
    UVa 11572 (滑动窗口) Unique Snowflakes
    UVa 1606 (极角排序) Amphiphilic Carbon Molecules
    UVa 11054 Wine trading in Gergovia
    UVa 140 (枚举排列) Bandwidth
  • 原文地址:https://www.cnblogs.com/tuchen/p/13869333.html
Copyright © 2011-2022 走看看