Description
小志的数学总是不及格,小强的爸爸为鼓励他学习,跟他打了个赌:如果他能答对一个问题,就给他一个糖果。这个问题是,有N张有数字的牌,牌上的数字分别是1,…,N,问从中选出M张牌,总和刚好是S的方案数有多少。小志不会回答,但又很想得到糖果,因此请求你的帮助。你能帮他拿到糖果吗?
Input
输入只有一行,包含三个整数,分别是总的牌数N,要选择的牌数M以及总和S。
Output
输出只有一行,包含一个整数,为所求的方案数,数据保证答案小于2^31。
数据范围:
对于30%的数据,M ≤ N ≤ 10;
对于80%的数据,M ≤ N ≤ 50;
对于所有的数据,M ≤ N ≤ 150,S ≤ 12000。
Source
elba
Analysis
dp显然,设
f[i][j][k]
表示前
i
项选
边界
f[i][0][0]=1
且
f[1][1][num[1]]=1
可以滚,不然空间不能过
细节挺多,不难想
Code
#include <cstdio>
using namespace std;
int num[151],f[2][151][12001];
int main()
{
int n,m,p;
scanf("%d%d%d",&n,&m,&p);
for (int i=1;i<=n;i++)
num[i]=i;
f[1][1][num[1]]=1;
f[0][0][0]=f[1][0][0]=1;
int x=1;
for (int i=2;i<=n;i++)
{
x^=1;
for (int j=1;j<=m;j++)
{
for (int s=0;s<=p;s++)
{
f[x][j][s]=f[x^1][j][s];
if (s>=num[i])
f[x][j][s]+=f[x^1][j-1][s-num[i]];
}
}
}
printf("%d\n",f[x][m][p]);
return 0;
}