蓝桥杯大赛— —每日一题(8、矩阵)

【问题描述】
把 1 ∼ 2020 放在 2 × 1010 的矩阵里。

要求同一行中右边的比左边大,同一列中下边的比上边的大。一共有多少种方案?

答案很大,你只需要给出方案数除以 2020 的余数即可。

答案提交
这是一道结果填空题,你只需要算出结果后提交即可。
本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

【我的思路】:
说实话,我当时在第一次看到这道题还真没想到会用动态规划来做,因为我原来一直是那种求最优解的时候才会想到用动态规划,看来还是我做题太少了,但是要是能想到用动态规划来做那也就不是很难了。
按照题目要求,要求把1 ∼ 2020放到2*1010的矩阵里,要求上面的小于下面的,左边的小于右边的,既然用动态规划,那么我们用dp[i][j]来保存将1~i+j的数放到第一行有i个数字,第二行有j个数字的矩阵的放法。注意,题中说同一列中下面的比上面的大,但是人家没说下面的一定比上面的小 ,这看起来是废话,但是也很重要,这就说明了我可以当一个数要放的时候(这个数肯定是当前矩阵中最大的数,不管放上面还是放下面都必须放在最右边,所以当确定放在哪一行那么这个状态dp[i][j]就等于在放这个数之前的那个状态值dp[i-1][j](放在上一行的之前的那个状态)或者是dp[i][j-1](放在下面一行的那个状态),因为你没得选,接下来要放的那个数字只能放在最右边)放在上面一行可以直接放没有限制,但是若要放在下面一行上面必须要有数字,即i>=j。但是如果i等于j,它的上一个状态就只能是dp[i][j-1],就是只能放在下面一行,因为你不可能放在上面一行,这样的话说明你前面有一个状态是下面一行的数字比上面一行的数字多一个(i = j-1),这是不合法的。所以思路就来了:if(i == j) dp[i][j] = dp[i][j-1];else dp[i][j] = dp[i-1][j]+dp[i][j-1];,当然还有初始条件,dp[i][0] = 1,就是1~i个数都放在第一行当然只有一种方法,按照1,2,3,……i,一次放进矩阵。现在直接上代码:

#include<iostream>
using namespace std;

int dp[1011][1011];

int main()
{
	for (int i = 1; i <= 1010; i++)
	{
		dp[i][0] = 1;
		for (int j = 1; j <= i; j++)
		{
			if (i == j) dp[i][j] = dp[i][j - 1];
			else
			{
				dp[i][j] = (dp[i-1][j] + dp[i][j-1])%2020;
			}
		}
	}
	cout<<dp[1010][1010]<<endl;
	return 0;
}

我接下来到蓝桥杯 比赛这段时间尽量每天做一道往年题目或者找到合适的发上来,一方面监督自己,一方面求大佬指正,希望一起进步一起学习哈!!!

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值