zoukankan      html  css  js  c++  java
  • bzoj1190:[HNOI2007]梦幻岛宝珠

    传送门

    二进制分组优化背包
    理解的差不多了,但是无法具体阐述,留坑
    代码:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<cstring>
    using namespace std;
    void read(int &x) {
    	char ch; bool ok;
    	for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
    	for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
    }
    #define rg register
    const int maxn=1010;
    vector<int>a[50],b[50];
    int n,m,f[50][maxn],w[maxn],len;
    int main()
    {
    	while(1)
    	{
    		memset(f,0,sizeof f);
    		memset(a,0,sizeof a);
    		memset(b,0,sizeof b);
    		memset(w,0,sizeof w);
    		read(n),read(m);len=0;
    		if(n==-1)return 0;
    		for(rg int i=1,j=0,x,y;i<=n;i++,j=0)
    		{
    			read(x),read(y);
    			while(!(x&1))x>>=1,j++;
    			a[j].push_back(x),w[j]+=x,
    			len=max(len,j),b[j].push_back(y);
    		}
    		for(rg int i=0;i<=len;i++)
    		{
    			int t=a[i].size();
    			for(int j=0;j<t;j++)
    			for(rg int k=w[i];k>=a[i][j];k--)
    				f[i][k]=max(f[i][k],f[i][k-a[i][j]]+b[i][j]);
    		}
    		while(m>>len)len++;len--;
    		for(rg int i=1;i<=len;i++)
    		{
    			w[i]+=(w[i-1]+1)/2;
    			for(rg int j=w[i];j>=0;j--)
    				for(rg int k=0;k<=j;k++)
    					f[i][j]=max(f[i][j],f[i][j-k]+f[i-1][min(w[i-1],(k<<1)|(m>>(i-1)&1))]);
    		}
    		printf("%d
    ",f[len][1]);
    	}
    }
    
  • 相关阅读:
    Vue cmd命令操作
    迭代器和生成器
    10-外键的变种 三种关系
    09-完整性约束
    08-数据类型(2)
    07-数据类型
    06-表的操作
    05-库的操作
    04-基本的mysql语句
    03-MySql安装和基本管理
  • 原文地址:https://www.cnblogs.com/lcxer/p/10492213.html
Copyright © 2011-2022 走看看