问题:有n种不同大小的数字ai,每种各mi个。判断是是否可以从这些数字中选出若干个使他们的和为k。
算法一
#include<stdio.h>
int a[100],m[100];
bool dp[100][100];
int main()
{
int n,w;
scanf("%d%d",&n,&w);
for(int i=0;i<n;i++)
scanf("%d%d",&a[i],&m[i]);
dp[0][0]=true;
for(int j=0;j<n;j++)
for(int k=0;k<=w;k++)//这里可以像上一篇文章用二进制思想优化
for(int i=0;i<=m[j]&&0<=k-i*a[j]&&i*a[j]<=k;i++)
dp[j+1][k] |= dp[j][k-k*a[j]];
puts(dp[n][w]?"Yes":"No");
return 0;
}
《挑战程序设计竞赛》P63
算法二
#include<stdio.h>
#include<string.h>
int dp[1000],a[1000],m[1000];
int main()
{
int n,k;
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++)
scanf("%d%d",&a[i],&m[i]);
memset(dp,-1,sizeof(dp));
dp[0]=0;
for(int i=0;i<n;i++)
for(int j=0;j<=k;j++)
if(dp[j]>=0)
dp[j]=m[i];
else if(j<a[i]||dp[j-a[i]]<=0)
dp[j]=-1;
else
dp[j]=dp[j-a[i]]-1;
puts(dp[k]>=0?"Yes":"No");
return 0;
}
这算法貌似只能判定可行性