背包DP。。短短20几行代码,调了我2个多小时。。吐血了,真心菜啊,对背包的理解不够透彻,就是这样的恶果,中间两个循环的次序写反了,前面我先循环的k,再循环的大小,这样导致有重复的子结构,就有重复方案。。唉,真郁闷
#include<stdio.h>
#include<string.h>
static int min(int a, int b)
{
return a < b ? a : b;
}
int main()
{
int i, j, k, l, n, size = 1 << 15, index = 0, a[200], dp[1 << 15][5];
for (i = 1; i * i < (1 << 15); i++)
a[index++] = i * i;
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
for (i = 0; i < index; i++)
for (j = min(size, a[i] * 4); j >= a[i]; j--)
for (k = 1; k <= 4 && (j - k * a[i] >= 0); k++)
for (l = 0; l + k <= 4; l++)
dp[j][l + k] += dp[j - k * a[i]][l];
while (scanf("%d", &n), n)
printf("%d\n", dp[n][4] + dp[n][3] + dp[n][2] + dp[n][1]);
return 0;
}