完全背包计数。
这里L1,L2可能会大于N。如果L2大于N,那么L2就当N处理就行了。如果L1大于N,那么肯定是0.
注意这里0元本身是一种情况,需要支付0个硬币。
用longlong。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#define ll long long
#define INF 2139062143
#define inf -2139062144
#define MOD 20071027
#define MAXN 30
using namespace std;
ll dp[305][305][305];
void init()
{
for(int i=0; i<=300; ++i) dp[i][0][0]=1;
for(int i=1; i<=300; ++i)
for(int j=1; j<=300; ++j)
for(int k=0; k<=300; ++k)
if(k>=i)
dp[i][j][k]=dp[i-1][j][k]+dp[i][j-1][k-i];
else
dp[i][j][k]=dp[i-1][j][k];
}
int main()
{
char str[100];
init();
while(gets(str))
{
int a[5]= {0},len=0,L=strlen(str);
for(int i=0; i<L; ++i)
{
if(isdigit(str[i])) a[len]=a[len]*10+str[i]-'0';
else len++;
}
int n=a[0],L1=a[1],L2=a[2];
ll ans=0;
if(len==0)
{
for(int i=0; i<=n; ++i)
ans+=dp[n][i][n];
}
else if(len==1)
{
L1=min(n,L1);
for(int i=0; i<=L1; ++i)
ans+=dp[n][i][n];
}
else
{
if(L1>n) ans=0;
else
{
L2=min(n,L2);
for(int i=L1; i<=L2; ++i)
ans+=dp[n][i][n];
}
}
printf("%lld\n",ans);
}
return 0;
}