题意:
问多重部分和能否恰好等于m。
思路:
dp[i][j]:用前i种面额硬币凑成j后,第i种硬币最多剩下的个数,若凑不成则为-1.可优化空间复杂度。
反思:
想不出应该如此定义dp数组。
代码:
#include <cstdio>
using namespace std;
int a[100 + 10];
int c[100 + 10];
int dp[100000 + 10];
int main()
{
int n, m;
while(scanf("%d %d", &n, &m) && n + m)
{
for(int i = 0; i < n; i++)
{
scanf("%d", &a[i]);
}
for(int i = 0; i < n; i++)
{
scanf("%d", &c[i]);
}
dp[0] = c[0];
for(int j = 1; j <= m; j++)
{
if(a[0] > j || dp[j - a[0]] <= 0)
{
dp[j] = -1;
}
else dp[j] = dp[j - a[0]] - 1;
}
for(int i = 1; i < n; i++)
{
for(int j = 0; j <= m; j++)
{
if(dp[j] >= 0)
{
dp[j] = c[i];
}
else if(a[i] > j || dp[j - a[i]] <= 0)
{
dp[j] = -1;
}
else
{
dp[j] = dp[j - a[i]] - 1;
}
}
}
int cnt = 0;
for(int i = 1; i <= m; i++)
{
if(dp[i] >= 0) cnt++;
}
printf("%d\n", cnt);
}
return 0;
}