zoukankan      html  css  js  c++  java
  • 梦幻岛宝珠「HNOI2007」

    题意

    (n)个宝石,每个宝石都有重量与价值,求总重量不超过(W)时的最大价值。(Wleq 2^{32})

    保证每个宝石的重量都可以被表示为(a*2^b)的形式。


    思路

    分组背包,对(b)分组,在每一组内跑01背包。

    每一组之间的转移有(f[i][j]=max(f[i][j],f[i][k]+f[i-1][min(1000,(j-k)<<1)+((W>>(i-1))&1)]))

    代码

    #include <bits/stdc++.h>
    
    using namespace std;
    
    namespace StandardIO {
    
        template<typename T> inline void read (T &x) {
            x=0;T f=1;char c=getchar();
            for (; c<'0'||c>'9'; c=getchar()) if (c=='-') f=-1;
            for (; c>='0'&&c<='9'; c=getchar()) x=x*10+c-'0';
            x*=f;
        }
        template<typename T> inline void write (T x) {
            if (x<0) putchar('-'),x=-x;
            if (x>=10) write(x/10);
            putchar(x%10+'0');
        }
    
    }
    
    using namespace StandardIO;
    
    namespace Solve {
    	
    	const int N=1001;
    	
    	int n,W,ans;
    	int w[N],v[N];
    	int f[N][N];
    
        inline void MAIN () {
    		while (1) {
    			read(n),read(W);
    			if (n==-1) return;
    			memset(f,0,sizeof(f)),ans=0;
    			for (register int i=1; i<=n; ++i) {
    				read(w[i]),read(v[i]);
    				int b=0,a=w[i];
    				while (!(a&1)) a>>=1,++b;
    				for (register int j=min(1000,W>>b); j>=a; --j) {
    					f[b][j]=max(f[b][j],f[b][j-a]+v[i]);
    					ans=max(ans,f[b][j]);
    				}
    			}
    			for (register int i=1; (1<<i)<W; ++i) {
    				for (register int j=min(1000,W>>i); j>=0; --j) {
    					for (register int k=j; k>=0; --k) {
    						f[i][j]=max(f[i][j],f[i][k]+f[i-1][min(1000,(j-k)<<1ll)+((W>>(i-1))&1ll)]);
    						ans=max(ans,f[i][j]);
    					}
    				}
    			}
    			write(ans),putchar('
    ');
    		}
        }
    
    }
    
    int main () {
        Solve::MAIN();
    }
    
  • 相关阅读:
    c++ fstream中seekg()和seekp()的用法
    java连接MySql数据库
    AspNetPager查询分页问题(点击页码,不再是查询后的数据集)viewstate解决
    C#操作XML文档
    关于PHP程序员解决问题的能力
    HDOJ 1874( dijkstra )
    错排问题 (Mathematics)
    中缀表达式到后缀表达式 (Data_Structure)
    几次到1(分治递归)
    max(int) = 0x7fffffff
  • 原文地址:https://www.cnblogs.com/ilverene/p/11384942.html
Copyright © 2011-2022 走看看