题意 :Whuacmers有n种硬币,分别是面值为A1,A2,.....,An,每一种面值的硬币的数量分别是C1,C2,......,Cn,Whuacmers想买钱包,但是想给人家刚好的钱,不喜欢再找钱那么麻烦,但是他不知道钱包的具体钱数,只知道不会超过m,所以问你手里的钱能表示多少个不超过m的钱数。
思路 :多重背包。不知道的去搜背包九讲,几乎都一样。
我想说这个小哥儿真逗
#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std ; int a[110],c[110] ; int dp[100010] ; bool vis[100010] ; int n, m; void zeroOnepack(int cost,int weight) { for(int i = m ; i >= cost ; i--) dp[i] = max(dp[i],dp[i-cost]+weight) ; } void completepack(int cost ,int weight) { for(int i = cost ; i <= m ; i++) dp[i] = max(dp[i],dp[i-cost]+weight) ; } void multiplepack(int cost,int weight,int amount) { if(cost * amount >= m) { completepack(cost,weight) ; return ; } else { int k = 1 ; while(k < amount) { zeroOnepack(k*cost,k*weight) ; amount -= k ; k = k*2 ; } zeroOnepack(amount*cost,amount*weight) ; } } int main() { while(~scanf("%d %d",&n,&m)) { if(n == 0 && m==0) break ; for(int i = 0 ; i < n ; i++) scanf("%d",&a[i]) ; for(int j = 0 ; j < n ; j++) scanf("%d",&c[j]) ; memset(dp,0,sizeof(dp)) ; int cnt = 0 ; for(int i = 0 ; i < n ; i++) { multiplepack(a[i],a[i],c[i]) ; } for(int i = 1 ; i <= m ; i++) if(dp[i] == i)cnt++ ; printf("%d ",cnt) ; } return 0 ; }