这题貌似是个权限题qwq,我是用离线题库+本地数据包测的
题目大意:
给你(n)个体积分别为(w[i])的物品和容积(m),问你将每一件物品分别去掉之后,拼出(1)~(m)中每一个体积的方案数的个位数分别是多少,将答案矩阵输出。
输入样例:
3 2
1 1 2
输出样例:
11
11
21
考虑先做一次01背包,得到(f)数组,然后去掉不合法的方案。怎么去掉呢,首先枚举第(i)件物品,令(g[x])表示不用第(i)件物品拼成体积为(x)的方案数,则(g)数组的转移如下:
1.(x<w[i],g[x]=f[x])
2.(x>=w[i],g[x]=f[x]-g[x-w[i]])(可以理解成先限制不选第(i)件物品,最后再选上,方案数就是总方案数减去不合法的方案数)
然后输出(g)数组就行了:
#include <bits/stdc++.h>
using namespace std;
#define N 2000
int n, m, w[N+5], f[N+5], g[N+5];
int main()
{
//freopen("2287.in", "r", stdin);
//freopen("2287.out", "w", stdout);
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++i) scanf("%d", &w[i]), w[i] = w[i] > m ? m+1 : w[i];
f[0] = 1;
for(int i = 1; i <= n; ++i)
for(int j = m; j >= w[i]; --j) f[j] = (f[j]+f[j-w[i]])%10;
for(int i = 1; i <= n; ++i)
{
for(int j = 0; j < w[i]; ++j) g[j] = f[j];
for(int j = w[i]; j <= m; ++j) g[j] = ((f[j]-g[j-w[i]])%10+10)%10;
for(int j = 1; j <= m; ++j) printf("%d", g[j]);
printf("
");
}
return 0;
}