题意:
中文题,就不解释题意了。
题解:
直接列为多项式 表示其方案数
例如第二个样例 列成三个 然后用母函数求出这三个连乘的多项式
指数为m的(去掉必须买的水果数剩下的m)系数就是答案。母函数的模版题。
板子是自己重新写的,好不好也不知道,能用就行。
这个题也可以用背包统计出答案,把代码也放上来了。
T_T练习赛的题目,只有自己傻傻的写了母函数,所以再写了一遍背包。
好久没写母函数的题目,板子重新自己写,调了半天= = 果然对这些理论性的东西不熟。
重新写了一遍,自己好好理解了就好。
母函数
#pragma comment(linker, "/STACK:102400000,102400000")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<vector>
using namespace std;
typedef long long ll;
const int N=1e2+5;
const int M=1e4+5;
ll fac[M];
struct node
{
int mn,mx;
}num[N];
int c1[N],c2[N],c3[N];
int main()
{
int n,m;
while (~scanf("%d%d",&n,&m))
{
int left=m;
for (int i=0 ; i<n ; ++i)
{
scanf("%d%d",&num[i].mn,&num[i].mx);
left-=num[i].mn;
}
for (int i=0 ; i<=left ; ++i)
{
if (i<=num[0].mx-num[0].mn)
c1[i]=1;
else
c1[i]=0;
c2[i]=0;
}
for (int i=1 ; i<n ; ++i)
{
for (int j=0 ; j<=left ; ++j)
{
if (j<=num[i].mx-num[i].mn)
c3[j]=1;
else
c3[j]=0;
}
for (int j=0 ; j<=left ; ++j)
{
for (int k=0 ; k+j<=left ; ++k)
c2[j+k]+=c1[j]*c3[k];
}
for (int j=0 ; j<=left ; ++j)
{
c1[j]=c2[j];
c2[j]=0;
}
}
printf("%d\n",c1[left]);
}
return 0;
}
背包
#pragma comment(linker, "/STACK:102400000,102400000")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<vector>
using namespace std;
typedef long long ll;
const int N=1e2+5;
int num[N],dp[N];
int main()
{
int n,m;
while (~scanf("%d%d",&n,&m))
{
for (int i=0 ; i<n ; ++i)
{
int x;
scanf("%d%d",&x,&num[i]);
m-=x;
num[i]-=x;
}
memset(dp,0,sizeof(dp));
dp[0]=1;
for (int i=0 ; i<n ; ++i)//n种物品
for (int j=m ; j>=1 ; --j)//总价值
for (int k=1 ; k<=num[i] && k<=j ; ++k)//取几件 价值为1
dp[j]+=dp[j-k];
printf("%d\n",dp[m]);
}
return 0;
}