zoukankan      html  css  js  c++  java
  • POJ1742:Coins

    浅谈(DP)https://www.cnblogs.com/AKMer/p/10437525.html

    题目传送门:http://poj.org/problem?id=1742

    多重背包,每个物品可以使用若干次的背包,我们只需要多枚举一次当前要使用多少次然后把这么多次结合在一起,当做(01)背包做即可。复杂度(O(sum cnt_im))(cnt_i)表示第(i)个物品的个数

    二进制分解优化:

    因为每个数必然可以被分解成若干个二进制数相加,所以我们就把(cnt_i)提前分解为若干个二进制数,把这么多个物品先打包成一个物品,做一遍(01)背包必然包含了选择任意个该物品的决策。

    时间复杂度:(O(sum log(cnt_i)m))

    空间复杂度:(O(m))

    代码如下:

    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    const int maxn=1e5+5;
    
    bool f[maxn];
    int n,m,tot,ans;
    int a[maxn],c[maxn],coin[maxn];
    
    int read() {
    	int x=0,f=1;char ch=getchar();
    	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
    	for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
    	return x*f;
    }
    
    int main() {
    	while(1) {
    		n=read(),m=read(),tot=ans=0;
    		if(!n&&!m)break;
    		memset(f,0,sizeof(f)),f[0]=1;
    		for(int i=1;i<=n;i++)a[i]=read();
    		for(int i=1;i<=n;i++)c[i]=read();
    		for(int i=1;i<=n;i++) {
    			for(int j=1;j<=512;j*=2)
    				if(c[i]>j)coin[++tot]=a[i]*j,c[i]-=j;
    			if(c[i])coin[++tot]=c[i]*a[i];
    		}
    		for(int i=1;i<=tot;i++)
    			for(int j=m;j>=coin[i];j--)
    				f[j]|=f[j-coin[i]];
    		for(int i=1;i<=m;i++)ans+=f[i];
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    百度地图地址解析/逆地址解析
    Oracle表空间创建要点
    dubbo——providers
    dubbo——常用标签属性
    dubbo——spring初始化
    dubbo——RPC
    mybatis——datasource
    redis——再补充
    mybatis——缓存
    mybatis——Executor
  • 原文地址:https://www.cnblogs.com/AKMer/p/10437687.html
Copyright © 2011-2022 走看看