01背包的最基本一维DP。。但我写了整整一个下午,是有多菜。。刚理解了一维背包的思路,发现本题还要保存路径,又卡了超久才想出一个方案来保存路径。。写的心力憔悴啊。。附上大牛的背包九讲地址,里面包含了很多的DP的思想,以后要慢慢研究
http://love-oriented.com/pack/pack2rc.pdf
#include<stdio.h>
#include<string.h>
int main()
{
int i, j, m, l, n, a[2001], dp[1001], path[1001], ans[1001];
while (scanf("%d %d", &m, &l), m || l)
{
scanf("%d", &n);
for (i = 1; i <= n; i++)
scanf("%d", &a[i]);
memset(dp, 0, sizeof(dp));
memset(path, 0, sizeof(path));
memset(ans, 0, sizeof(ans));
for (i = 1; i <= n; i++)
{
for (j = m; j >= a[i]; j--)
{
if (dp[j - a[i]] + a[i] > dp[j])
{
path[j] = i;
dp[j] = dp[j - a[i]] + a[i];
}
if (i == n && j == m)
break;
}
}
int index = m, total = 0;
while (path[index])
{
ans[path[index]] = 1;
total++;
index = dp[index] - a[path[index]];
}
int sum = 0, flag = 1;
for (i = 1; i <= n && flag; i++)
{
if (!ans[i])
sum += a[i];
if (sum > l)
flag = 0;
}
if (flag)
{
printf("%d", total);
for (i = 1; i <= n; i++)
if (ans[i])
printf(" %d", i);
putchar('\n');
}
else
puts("Impossible to distribute");
}
return 0;
}