• CodeForces 572C. Lengthening Sticks(不定方程的根的方案个数)


    题意:给你三条边(x,y,z),你可以给三条边各自增加任意数值,但是增加的总和最多为(w)。求可以组成三角形的方案数。

    分析:设(x y z)的增量为p1,p2,p3,假定(p1 + p2 + p3 = t,tin{[0, w]}),题目中要求的增量可以为0,如果按平常来说,对于形如(p1 + p2 + p3 = t,p1, p2, p3 > 0)的方程,这是不定方程的正整数根的方案个数,我们的求法是(隔板法),不定方程的正整数根的方案个数为(C_{t - 1}^{2}),然后如果不定方程的根是>=0的话,怎么办?我们可以做一个映射,(p1 + 1 + p2 + 1 + p3 + 1 = t + 3),令(q1 = p1 + 1, q2 = p2 + 1, q3 = p3 + 1),那么(q1 + q2 + q3 = t + 3),那么总的方案数为(sumlimits_{t = 0}^{t = w}C_{t + 2}^{2})。然后我们开始考虑不合法的方案,即(x + q1 >= y + q2 + z + q3)的方案数,我们可以得到(q1 >= y + z + q2 + q3 - x),因为(q1 + q2 + q3 = t),我们令(q2 + q3 = u,q1 = t - u),那么可以得到(t - u >= y + z - x + u),令(y + z - x = c)(c)是一个常数,(t - u >= c + u),那么可以得到(u <= frac{(t - c)}{2}),那么这种方案数有多少呢,即q2和q3的取法,我们依然可以使用隔板法,前面的球个数有p1个,后面有u = p2 + p3个,我们来分割u,可以发现有(frac{(u + 2) * (u + 1)}{2})种方案数,我们依次减掉x,y,z作为最长边的方案数即可。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <algorithm>
    
    using namespace std;
    using LL = long long;
    
    LL solve(int x, int y, int z, int t)
    {
    	LL c = t - (y + z - x);
    	if (c < 0) return 0;
    	else
    	{
    		c = c / 2;
    	}
    	if (c > t) c = t;
    	return (LL)(c + 2) * (c + 1) / 2;
    }
    
    int main()
    {
    	int x, y, z, w;
    	cin >> x >> y >> z >> w;
    
    	LL res = 0;
    	for (int i = 0; i <= w; ++i)
    	{
    		res += (LL)(i + 2) * (i + 1) / 2;
    	}
    
    	for (int i = 0; i <= w; ++i)
    	{
    		res -= solve(x, y, z, i);
    		res -= solve(y, x, z, i);
    		res -= solve(z, x, y, i);
    	}
    
    	cout << res << endl;
    
    	return 0;
    }
    
  • 相关阅读:
    [C语言]数据类型与计算
    [C语言]变量VS常量
    [C语言]在命令行编译执行程序
    [cocos2d-x]游戏开发基础(图)
    [cocos2d-x]移动平台游戏开发(图)
    [cocos2d-x]认识游戏开发(图)
    [jQ/PHP]再谈使用JS数组储值的运用(提交PHP处理)
    [Nginx]Nginx的基本配置与优化1(完整配置示例与虚拟主机配置)
    [JS]如何理解JS中的类和对象
    [jPlayer]一分钟部署jPlayer
  • 原文地址:https://www.cnblogs.com/pixel-Teee/p/13280967.html
Copyright © 2020-2023  润新知