动态规划求解最多有几种方案求解硬币找零问题
15546
15546
5841
18381
w和dp的数组不够大,需要10^5的大小,改过以后会TLE
// TLE
#include <iostream>
#include <algorithm>
using namespace std;
#define maxm 100010
#define maxn 101
int main(int argc, char *argv[])
{
int n, m, i, j, count, count1;
int v[maxn], num[maxn];
int w[maxm], dp[maxm];
while (scanf("%d%d", &n, &m) && (n || m))
{
i = 0;
memset(dp, 0, sizeof(dp));
count = count1 = 0;
for (i = 0; i < n; i++)
scanf("%d", &v[i]);
for (i = 0; i < n; i++)
scanf("%d", &num[i]);
j = 0;
for (i = 0; i < n; i++)
{
while (num[i]--)
{
w[j++] = v[i];
count1++;
}
}
for (i = 0; i < count1; i++)
{
for (j = m; j >= w[i]; j--)
{
dp[j] = max(dp[j], dp[j - w[i]] + w[i]);
}
}
count1 = 0;
for (i = 1; i <= m; i++)
{
if (dp[i] == i)
{
count1++;
}
}
printf("%d\n", count1);
}
return 0;
}
这题正确的做法应该加上背包的二进制优化或者单调队列优化
用母函数来做也是可以的
// AC...
#include <iostream>
#include <algorithm>
using namespace std;
#define maxm 100010
#define maxn 101
int main(int argc, char *argv[])
{
int n, m, i, j, k, count1;
int v[maxn], num[maxn];
int dp[maxm];
while (scanf("%d%d", &n, &m) && (n || m))
{
i = 0;
memset(dp, 0, sizeof(dp));
for (i = 0; i < n; i++)
scanf("%d", &v[i]);
for (i = 0; i < n; i++)
scanf("%d", &num[i]);
for (i = 0; i < n; i++)
{
for (j = m; j >= 0; j--)
{
if (dp[j] != j) continue;
for (k = 1; k <= num[i]; k++) {
count1 = j + k*v[i];
if (count1 > m) break;
if (dp[count1]) break;
dp[count1] = count1;
}
}
}
count1 = 0;
for (i = 1; i <= m; i++)
{
if (dp[i] == i)
{
count1++;
}
}
printf("%d\n", count1);
}
return 0;
}
8722
21307
11694