2022南阳理工校赛A题(比较蠢但是容易想到的思路

题目链接

题目详情 - 湮灭残昼 - 南阳理工学院OJ (nyist.edu.cn)

太痛了太痛了 第一次遇见错误类型TOO-LATE,赛后学长给我说这题过了,晚交了十秒的痛啊!!!

 

其实我这题的解题思路就是一个顺着往下想的过程,开赛就打开A上来一个自信dfs交上去 然后wa,在一细看就发现好像不太对,没有考虑0组成数字的情况,此时赛时已经达到了14分钟……

下面就是大致思路,wa掉的dfs不要扔,裹上面包糠,塞进二维数组就能打出来一个由n个正整数组成m的所有可能性,图长这个样

这应该就是一个杨辉三角的样子(后来某某佬提到才意识到原来就是杨辉三角

然后dfs就可以删掉了,改成box[i][j]=box[i-1][j-1]+box[i-1][j]

接下来考虑包含0的情况

假设需要我们求由5个数组成10的所有可能数量,那么在取出box的box[5][10]之后,再考虑由1个0和4个正整数组成10的情况数量,此时只需要求出这一个0在n=5个位置选哪一个即可,即C5 1,五个位置选出一个放0,等于5,5*4个正整数组成10的数量(box[10][4])

然后是由2个0和3个正整数组成10的情况,同理即C5 2五个位置选2个位置放0,等于10,10*box[10][3]

依此类推

而关于Cmn的求法,如果直接求出分子分母再相除必会爆long long,而边乘分子然后除分母则会用到浮点数,就会出现精度问题容易出错(但也能写),所以我们可以选择让分母从小到大乘,分子从大到小乘,就可以得出来结果。

ps:为什么这样乘就不会出现精度问题了?佬们想一想肯定就能想到了,先*1,则分子若存在1的倍数即可消掉分母的1,再乘2,分子出现2的倍数即可消掉,而每两个数必有一个2的倍数,分母*3时分子也必然是连续的三个数,也就能消掉分母的3了

结果大概就是这个情况了,思路可能很麻烦,但是很好理解捏

已ac代码:

#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<math.h>
#include<string.h>
#include<stack>
#include<queue>
#define ll long long
using namespace std;
const int maxn = 1e5 + 10;
int n, m;
ll box[25][25], ans[25][25];
ll c(int m, int n)  //组合数的函数 
{
	ll ans = 1;
	for (ll i = 1; i <= n; i++, m--) {
		ans *= m;
		ans /= i;
	}
	return ans;
}
int main()
{
	for (int i = 1; i <= 20; i++) {
		box[i][1] = 1;
		ans[i][1] = box[i][1];
	}
	for (int i = 2; i <= 20; i++) {
		for (int j = 2; j <= 20; j++) {
			box[i][j] = box[i - 1][j - 1] + box[i - 1][j];
			ans[i][j] = box[i][j];
			ll k = j, l = 1;
			while (k--) {
				ans[i][j] += box[i][k]*c(j,l);
				l++;
			}
		}
	}
    int a, b;
    cin>>a>>b;
    cout<<ans[a][b];
	return 0;
}

by yq

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

超高校级のDreamer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值