#include
const int MAX = 1000;
int n, m, M, a[MAX], dp[MAX + 1][MAX + 1];
void print(int row, int col)
{
printf("i/j |");
for (int i = 0; i <= col; i++)
printf("%4d", i);
printf("\n-----");
for (int i = 0; i <= col; i++)
printf("----");
for (int i = 0; i <= row; i++)
{
printf("\n%3d |", i);
for (int j = 0; j <= col; j++)
printf("%4d", dp[i][j]);
}
}
int main()
{
freopen("E:/My/input.txt", "r", stdin);
scanf("%d%d%d", &n, &m, &M);
printf("n = %d, m = %d, M = %d\n", n, m, M);
for (int i = 0; i < n; i++)
scanf("%d", a + i);
for (int i = 0; i <= n; i++)
dp[i][0] = 1;
for (int i = 0; i < n; i++)
for (int j = 1; j <= m; j++)
if (j > a[i])
dp[i + 1][j] = (dp[i + 1][j - 1] + dp[i][j] - dp[i][j - 1 - a[i]] + M) % M;
else
dp[i + 1][j] = (dp[i + 1][j - 1] + dp[i][j]) % M;
printf("result = %d\n", dp[n][m]);
print(m, n);
return 0;
}
const int MAX = 1000;
int n, m, M, a[MAX], dp[MAX + 1][MAX + 1];
void print(int row, int col)
{
printf("i/j |");
for (int i = 0; i <= col; i++)
printf("%4d", i);
printf("\n-----");
for (int i = 0; i <= col; i++)
printf("----");
for (int i = 0; i <= row; i++)
{
printf("\n%3d |", i);
for (int j = 0; j <= col; j++)
printf("%4d", dp[i][j]);
}
}
int main()
{
freopen("E:/My/input.txt", "r", stdin);
scanf("%d%d%d", &n, &m, &M);
printf("n = %d, m = %d, M = %d\n", n, m, M);
for (int i = 0; i < n; i++)
scanf("%d", a + i);
for (int i = 0; i <= n; i++)
dp[i][0] = 1;
for (int i = 0; i < n; i++)
for (int j = 1; j <= m; j++)
if (j > a[i])
dp[i + 1][j] = (dp[i + 1][j - 1] + dp[i][j] - dp[i][j - 1 - a[i]] + M) % M;
else
dp[i + 1][j] = (dp[i + 1][j - 1] + dp[i][j]) % M;
printf("result = %d\n", dp[n][m]);
print(m, n);
return 0;
}
又是一下午,跪了...
if (a[i] >= j) $dp[i][j - k] = dp[i][j] + dp[i][j - 1] + ... + dp[i][0];
else $dp[i][j - k] = dp[i][j] + dp[i][j - 1] + ... + dp[i][j - a[i] + 1] + dp[i][j - a[i]];
//else令j=j-1 $dp[i][j-1 - k] = dp[i][j-1] + dp[i][j-1 - 1] + ... + dp[i][j-1 - a[i] + 1] + dp[i][j-1 - a[i]];
整理 $dp[i][j - 1 - k] = dp[i][j - 1] + dp[i][j - 2] + ... + dp[i][j - a[i]] + dp[i][j - 1 - a[i]];
对比上面可以看出少了什么多了什么,所以有:
if (a[i] >= j) $dp[i][j - k] = $dp[i][j - 1 - k] + dp[i][j] - dp[i][j - 1 - a[i] < 0];
else $dp[i][j - k] = $dp[i][j - 1 - k] + dp[i][j] - dp[i][j - 1 - a[i] >= 0];
和上一篇同样,建议直接赋值i=1这行,从i=2开始循环。(或许这种题的套路就是这样?i=0这行的初始元素是1 0 0 ... 0就行?不懂,求解)
n = 3, m = 3, M = 10000
result = 6
i/j | 0 1 2 3
---------------------
0 | 1 0 0 0
1 | 1 1 0 0
2 | 1 2 2 1
3 | 1 3 5 6