方案数【DP】

>Description
小志的数学总是不及格,小强的爸爸为鼓励他学习,跟他打了个赌:如果他能答对一个问题,就给他一个糖果。这个问题是,有N张有数字的牌,牌上的数字分别是1,…,N,问从中选出M张牌,总和刚好是S的方案数有多少。小志不会回答,但又很想得到糖果,因此请求你的帮助。你能帮他拿到糖果吗?


> Input
输入只有一行,包含三个整数,分别是总的牌数N,要选择的牌数M以及总和S。
输出


> Output
输出只有一行,包含一个整数,为所求的方案数,数据保证答案小于2^31。


> Sample Input
9 5 18


> Sample Output
3


> Hint
数据范围: 对于30%的数据,M ≤ N ≤ 10; 对于80%的数据,M ≤ N ≤ 50; 对于所有的数据,M ≤ N ≤ 150,S ≤ 12000。


> 解题思路
这一题用DP解。我一开始看得也很懵,后来一直看一直看就看明白了。数组f就是f [取几个数] [取的数的总和]


> 代码

#include<iostream>
#include<cstdio>
using namespace std;
int f[155][12005],n,m,s,maxn={0};
int main()
{
	scanf("%d%d%d",&n,&m,&s);
	f[0][0]=1;//设初值
	for(int i=1;i<=n;i++)
	{
		for(int j=m;j>=0;j--)//枚举要取的个数
		 for(int t=maxn;t>=0;t--)//枚举当前数i加上的数
		  if(f[j][t]!=0)//这一段可要可不要,有了只是更快一点而已 
		    f[j+1][i+t]+=f[j][t];
		maxn+=i;
	}
	printf("%d",f[m][s]);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43010386/article/details/83446493