首页 > 其他分享 >P3799 妖梦拼木棒(组合数学)

P3799 妖梦拼木棒(组合数学)

时间:2023-12-11 22:46:37浏览次数:32  
标签:妖梦 组合 min 木棒 个数 int P3799 ans include

P3799 妖梦拼木棒

又是一道要靠题解的思路的题。(难受)。

解题思路

首先,由于数据大小在5*1e3以内,数据量在1e5以内。所以用桶排记录无疑是最合适的。(记录下数据的最大值和最小值可以提高运行效率)
由题目分析,4个木棒中分三份(每份不为0)必然为1,1,2.
其次,我们用循环i遍历数组b[],取b[i]为三角形的边长(边长不可能是最小值,所以i=min+1),如果b[i]的个数不小于2,那么这个正三角形才有可能成立,当它成立时,我们再用一个循环j从b[min]遍历到b[i/2](把i分为两部分取i小的部分为j,j最大值应该为i/2).b[j]和b[i-j]就是组成b[i]的两部分。当这两部分存在时,分析此时的能组成的正三角形的个数。
最后再把答案相加起来就好了(注意每次加答案时都要对答案取mod)

这里用到数学组合思想

如果当n=2.
组合数=n*(n-1)/2。

当我们知道这个这个数学组合思想后便可以对这个三角形进行分解。
总的可能个数=两个相同的数的组合数*能相加组成与两个相同的数的数的个数。
这样我们就能非常好的计算出再某种情况下正三角形的个数

个人想法

感觉非常秒,数学组合数在n=2时的情况可以直接对数进行运算,如果当n>=3时应该就得通过循环(本人菜鸡还不知道其他方法)来得到组合数的值。可以有效提升计算效率

#include <iostream>
#include <string>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 1e5 + 5;
const int M = 1e9 + 7;
int a[N], b[N];
int ans;

int main() {
	int  n;
	cin >> n;
	int max = 0;
	int min = N;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		if (a[i] > max) {
			max = a[i];
		}
		if (a[i] < min) {
			min = a[i];
		}
		b[a[i]]++;
	}
	for (int i = min + 1; i <= max; i++) {
		if (b[i] <= 1) {
			continue;
		} else {//只有b[i]>=2时才有可能成立。
			for (int j = min; j <= i / 2; j++) {
				if (b[j] >= 1 && b[i - j] >= 1) {
					if (j * 2 == i) {
						ans += b[i] * (b[i] - 1) * b[i / 2] * (b[i / 2] - 1) / 4;//这就相当于两个组合数的数相乘
					} else {
						ans += b[i] * (b[i] - 1) / 2 * b[j] * b[i - j];//两个相同的数的组合数*能相加组成与两个相同的数的数的个
					}
				}
			}
			ans %= M;//记得每次都要取mod
		}
	}
	cout << ans % M;
	return 0;
}

标签:妖梦,组合,min,木棒,个数,int,P3799,ans,include
From: https://www.cnblogs.com/sdlypsck/p/17895761.html

相关文章

  • AcWing 167. 木棒 (剪枝非常多的一道搜索题
    package算法提高课;importjava.util.Arrays;importjava.util.Scanner;publicclassacw167{staticint[]w;staticboolean[]st;staticintsum,len,n;/***本题剪枝比较多光介绍一下,本代码注释光介绍一下剪枝的大概思路,如果有遗忘或......
  • 木棒
    #include<iostream>#include<string.h>#include<algorithm>usingnamespacestd;constintN=70;intn;intw[N];intsum;boolst[N];intlen;//dfs蹦着跳着......
  • C++算法之旅、02 从木棒切割问题领悟二分法精髓
    172、木棒切割问题https://sunnywhy.com/problem/172题目描述给出n根木棒的长度,现在希望通过切割它们来得到至少k段长度相等的木棒(长度必须是整数),问这些长度相等的木......
  • 木棒
    https://www.acwing.com/problem/content/169/#include<cstring>#include<iostream>#include<algorithm>usingnamespacestd;constintN=70;intn;intw[......
  • [AcWing 167] 木棒
    DFS剪枝点击查看代码#include<bits/stdc++.h>usingnamespacestd;typedeflonglongLL;constintN=1e6+10;intn;intw[N];intsum,len;boolst......