您的位置:首页 > 产品设计 > UI/UE

2016 UESTC Training for Math A - 谭爷的黑暗沙拉 组合学

2016-07-09 01:14 549 查看


A - 谭爷的黑暗沙拉


Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)


Submit
Status

谭爷有n种不同种类的食材(水果&蔬菜),他想做出一份总重量为k的黑暗沙拉。
他想让机智的你告诉他,他能做多少种不同的黑暗沙拉!
说明:
1.可以重复选择食材,而且不需要选完全部的n种食材,但是最后总重量必须是k。
2.两份沙拉不同,当且仅当k重量食材的种类或配比不同。
3.每种食材只能选择非负整数的重量加入沙拉。


Input

一行,两个正整数n,k;
1<=n,k<=25;


Output

一行,一个非负整数,方案数目。 (请用long long)


Sample input and output

Sample InputSample Output
3 2

6


Hint

设如果食材编号1,2
最终沙拉可以是
有(1,1),(1,2),(1,3),(2,2),(2,3),(3,3)六种。


Source

2016 UESTC Training for Math


My Solution

排列组合中的隔板法

常用来求 x1 + x2 + ...... + xn = k的非负解的个数,

每个盒子里 -1 +1 转化为每个盒子里有 -1 个球,

然后对于 k + n 个球插入 n - 1 个隔板

即 y1 + y2 + ...... yn = k + n;

C(k + n - 1, n - 1)

然后主意 k, n <= 25 ,乱做即使 long long 也会溢出

故在中间过程就要把A(n - 1, n - 1)约掉

最开始先约大的,这样显然不行(WA9), 大的不容易约去, 可能还没有约去的时候,ans已经溢出了

要从小的开始约先检查能不能约去2, 然后3 直到 n-1.

while(ptr <= n - 1 && ans % ptr == 0) {ans /= ptr; ptr++;}

这个要记牢了(┬_┬),嘿嘿

复杂度 O(1)

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long LL;

int main()
{
LL n, k, ans = 1;
scanf("%lld%lld", &n, &k);
LL ptr = 2;
for(LL i = k + n - 1; i >= k + 1; i--){
ans *= i;
//!while(ptr > 1 && ans % ptr == 0) {ans /= ptr; ptr--;}  //应该从小的开始约去吗
while(ptr <= n - 1 && ans % ptr == 0) {ans /= ptr; ptr++;}
}
printf("%lld", ans);
return 0;
}


Thank you

------from ProLights
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: