题目大意:
有1到300的价值的硬币,给你一个价值n,后面跟着0~2个数字,
0个数字表示你要用1~n个硬币,去凑成价值n,
1个数字a表示你要用a枚或者更少的硬币,去凑成这个价值,
2个数字a,b表示你用a到b范围内的硬币,去凑成这个价值。
输出方法数。
思路:
dp[i][j] 表示i可以拆分成多少个不大于j的数字组合。
有两种情况
1. 包括j:dp[i][j] += dp[i-j][j];
有1到300的价值的硬币,给你一个价值n,后面跟着0~2个数字,
0个数字表示你要用1~n个硬币,去凑成价值n,
1个数字a表示你要用a枚或者更少的硬币,去凑成这个价值,
2个数字a,b表示你用a到b范围内的硬币,去凑成这个价值。
输出方法数。
思路:
dp[i][j] 表示i可以拆分成多少个不大于j的数字组合。
有两种情况
1. 包括j:dp[i][j] += dp[i-j][j];
2. 不包括j:dp[i][j] += dp[i][j-1];
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <sstream>
using namespace std;
typedef long long ll;
const int N = 1010;
ll dp[N][N];
void init() {
memset(dp,0,sizeof(dp));
dp[0][0] = 1;
for(int i = 0; i < N; i++) {
for(int j = 1; j < 305; j++) {
if(i - j >= 0) { //用j
dp[i][j] += dp[i-j][j];
}
//不用j
dp[i][j] += dp[i][j-1];
}
}
}
int main() {
init();
char line[N];
int n,l1,l2;
while(gets(line)) {
l1 = l2 = -1;
sscanf(line,"%d%d%d",&n,&l1,&l2);
l1 = min(l1,300);
l2 = min(l2,300);
if(l1 == -1) {
printf("%lld\n",dp[n][n]);
}else if(l2 == -1) {
printf("%lld\n",dp[n][l1]);
}else {
printf("%lld\n",dp[n][l2] - dp[n][l1-1]);
}
}
return 0;
}