题目列表:
2020年:矩阵
2021年:砝码称重
3道经典线性DP问题(可能会考到类似的题哦):
摆花
合唱队形
导弹拦截
1道经典区间DP问题
石子合并
1.矩阵
把 1 ∼ 2020 放在 2 × 1010 的矩阵里。
要求同一行中右边的比左边大,同一列中下边的比上边的大。一共有多少种方案?
答案很大,你只需要给出方案数除以 2020 的余数即可。
答案:1430
分析:
这道题和“杨老师的照相排列”是同类型的题(“杨老师的照相排列”这道题属于经典题型,建议记住!!)
既然说到了,我们就来总结一下这一类的模板:
将1~N的这N个数放在k行中,每一行的数从左到右依次递增,每一列的数从前到后依次递增,问有多少种排法?
这里的k我们假设为5
我们在排的时候的前提就是:前一排的数一定要大于后一排的数
s[0]~s[4]分别是第一排~第五排需要站的人数
f[a][b][c][d][e] 表示第一排a人,第二排b人,第三排c人,第四排d人,第五排e人时的方案数
f[0][0][0][0][0] = 1;
for (int a = 0; a <= s[0]; a ++ )
for (int b = 0; b <= s[1]; b ++ )
for (int c = 0; c <= s[2]; c ++ )
for (int d = 0; d <= s[3]; d ++ )
for (int e = 0; e <= s[4]; e ++ ){
LL &x = f[a][b][c][d][e];
if (a && a - 1 >= b){
x += f[a - 1][b][c][d][e];//第一排人数必须大于第二排
}
if (b && b - 1 >= c){
x += f[a][b - 1][c][d][e];//第二排人数必须大于第三排
}
if (c && c - 1 >= d){
x += f[a][b][c - 1][d][e];//第三排人数必须大于第四排
}
if (d && d - 1 >= e){
x += f[a][b][c][d - 1][e];//第四排人数必须大于第五排
}
if (e){
x += f[a][b][c][d][e - 1];
}
}
cout << dp[s[0]][s[1]][s[2]][s[3]][s[4]];
然后我们开始写这道题的代码把!
代码:
#include<iostream>
using namespace std;
int dp[1015][1015];
int main(){
dp[0][0] = 1;
for(int i = 0;i <= 1010;i++){
for(int j = 0;j <= 1010;j++){
if(i && i-1 >= j){
dp[i][j] += dp[i-1][j]%2020;
}
if(j){
dp[i][j] += dp[i][j-1

最低0.47元/天 解锁文章
1023

被折叠的 条评论
为什么被折叠?



