zoukankan      html  css  js  c++  java
  • 数论训练之三

    http://codeforces.com/problemset/problem/571/A

    冥思苦想怎么加才能保证能组成三角形,并且要求其方案数

    然后就无奈看题解

    发现其实可以容斥一下总方案数-不合法的方案数=答案

    普及一下排列组合

    P(n,m)表示n个中选出m个排列

    P(n,m)=n(n-1)(n-2)(n-3)....(n-m+1)=n!/(n-m)!

    分别表示第一个位置可以选的数有n

    第二个可以选的数有n-1个(排除第一个选的)

    。。。。。。

    特别的

    p(n,n)=n!

    特别的

    当有N1个元素相等,N2个元素相等,N3个元素相等.......Nm个元素相等,且N1+N2+N3+.....+Nm=N

    叫可重集的排列

    P=N!/(N1!N2!....Nm!)

    C(n,m)表示从n个中选出m个不同的组合

    C(n,m)=P(n,m)/p(m,m)=n!/(n-m)!m!

    特别的

    可重复组合为C(n+m-1,m)

    插板法为C(n+m-1,m-1)

    回到正题

    对于本题来说就可以用插板法

    只要满足下面3个条件之一即可

    a+x+b+y<=c+z

    a+x+c+z<=b+y

    b+y+c+z<=a+x

    而且这三个条件最多只会有一个成立!!!!!!!!

    另外还要满足x+y+z<=l

    对于第一种,即为x+y<=min(c+z-a-b,l-z)方案数

    枚举z即可

    其他两种同理

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    typedef long long ll;
    using namespace std;
    int a,b,c,l;ll ans;
    
    ll f(int a,int b,int c){
    	ll res=0;
    	for (int i=0;i<=l;i++){
    		int t=min(l-i,c+i-a-b);
    		if (t>=0) res+=1ll*(t+2)*(t+1)/2;
    	}
    	return res;
    }
    
    int main(){
    	scanf("%d%d%d%d",&a,&b,&c,&l);
    	for (int i=0;i<=l;i++) ans+=1ll*(i+2)*(i+1)/2;
    	ans-=f(c,b,a),ans-=f(b,a,c),ans-=f(c,a,b);
    	printf("%I64d
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    学生管理系统后感
    数据库是什么鬼,怎么连接,怎么搞
    nIce 不看会后悔的o!
    那些年披巾斩浪的数据库
    day82
    day81
    day80
    day79
    day78
    day77
  • 原文地址:https://www.cnblogs.com/wzxbeliever/p/11642262.html
Copyright © 2011-2022 走看看