题目:
Description
Input
Output
Sample Input
3 10 1 2 4 2 1 1 2 5 1 4 2 1 0 0
Sample Output
8 4题目意思就是:
一定量的硬币,问可以凑出多少不同的价值。
之所以做这题,是因为在LTC的男人八题看到的。
之前其实真的没做过可行性背包,当时第一反应就是拍了一个优化的多重背包,结果果然是TLE了。之后看题解,原来有O(nm)的姿势,补上。
最近改用vim了!codeblocks,byebye!
周日就是GDCPC了,虽然队伍的缺陷非常多,但是,尽力吧!
/*************************************************************************
> OS : Linux 3.2.0-60-generic #91-Ubuntu
> Author : yaolong
> Mail : dengyaolong@yeah.net
> Created Time: 2014年05月09日 星期五 10:23:35
************************************************************************/
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
using namespace std;
#define MAXN 105
#define MAXV 100005
int cnt[MAXN],val[MAXN];
int used[MAXV];
bool f[MAXV];
int n,V;
int coins;
/*可行性背包,当问题仅仅是问能否装到,那么只要达到过就不要再做了*/
void AMultipack(int val,int num){
memset(used,0,sizeof(used));
for(int j=val;j<=V;j++){
if(!f[j]&&f[j-val]&&used[j-val]<num){
//要求f[j]没有存在过,但是f[j-val]是之前达到的,且还可以购买
f[j]=true;
used[j]=used[j-val]+1;
coins++;
}
}
}
int main(){
int n;
int i,j,k;
while(scanf("%d%d",&n,&V)&&(n||V)){
for(i=0;i<n;i++){
scanf("%d",val+i);
}
for(i=0;i<n;i++){
scanf("%d",cnt+i);
}
coins=0;
memset(f,0,sizeof(f));
f[0]=true;
for(i=0;i<n;i++){
AMultipack(val[i],cnt[i]);
}
printf("%d\n",coins);
}
return 0;
}
原文地址:http://blog.csdn.net/dengyaolongacmblog/article/details/25380863