01背包:TYVJ1096-数字组合
题目链接:http://www.joyoi.cn/problem/tyvj-1096
题目大意
给N个正整数,求能组成M的方法有多少种
解题思路
不是说了吗,01背包呀!
code
#include<cstdio>
using namespace std;
int n,m,a[101],f[10001];
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%d",&a[i]);f[0]=1;for(int i=1;i<=n;i++)for(int j=m;j>=a[i];j--)f[j]+=f[j-a[i]];printf("%d",f[m]);
}
完全背包:TYVJ1172-自然数拆分Lunatic版
题目链接:http://www.joyoi.cn/problem/tyvj-1172
题目大意
给定一个数N,求有多少种方法可以将N拆分成若干个正整数。
解题思路
不是说了吗,完全背包呀!
code
#include<cstdio>
#define BPM 2147483648u
using namespace std;
int n;
unsigned int f[4001];
int main()
{scanf("%d",&n);f[0]=1;for(int i=1;i<=n;i++)for(int j=i;j<=n;j++)f[j]=(f[j]+f[j-i])%BPM;printf("%d",f[n]>0?f[n]-1:2147483647);
}
完全背包:POJ1742-Coins
题目链接:http://poj.org/problem?id=1742
题目大意
每个不同的币值有不同的个数,求能组合成m的方案数
解题思路
不是说了吗,多重背包呀!
然而会WA。
我们可以用一个use储存已经使用不同的币值时的已经使用个数。
code
#include<cstring>
#include<cstdio>
using namespace std;
int a[111],n,m,c[111],use[100011],ans;
bool f[100011];
int main()
{while(true){scanf("%d%d",&n,&m);memset(f,0,sizeof(f));ans=0;if(!n&&!m) return 0;for (int i=1;i<=n;i++)scanf("%d",&a[i]);for(int i=1;i<=n;i++)scanf("%d",&c[i]);f[0]=1;for (int i=1;i<=n;i++){memset(use,0,sizeof(use));for(int j=a[i];j<=m;j++)if(!f[j]&&f[j-a[i]]&&use[j-a[i]]<c[i])f[j]=true,use[j]=use[j-a[i]]+1,ans++;}printf("%d\n",ans);}
}