Time limit per test: 2.0 seconds
Memory limit: 512 megabytes
唐纳德先生的某女性朋友最近与唐纳德先生同居。该女性朋友携带一 baby。该 baby 酷爱吃棒棒糖,且有一个奇怪的特性:今天吃的棒棒糖一定要比昨天的棒棒糖更多,至少要一样多。如果棒棒糖少了,baby 就会很不高兴;另外如果有连续 k 天棒棒糖的数量都是一样的,baby 也会很不高兴。
唐纳德先生发现他的口袋里只有可怜的 n 元钱,他可以用 1 元钱买 1 根棒棒糖。他想用这些钱逗 baby 开心,这些钱可以不花完。他可以从某一天开始再也不买棒棒糖,把他的女性朋友和 baby 一起送回家;但是他绝对不能让 baby 不高兴,否则他的女性朋友可能对他做一些不和谐的事情。
唐纳德先生想要知道,他总共有多少种买棒棒糖的方案,两种方案不相同当且仅当总天数不相同,或者某一天买的棒棒糖数量不相同。唐纳德先生知道这个问题对于聪明的你实在是太简单了,所以他加了一个附加条件:他第一天必须买棒棒糖,而且至少买 x 根棒棒糖。
Input
一行三个整数 n,x,k 。
数据范围约定:
- 对于 Easy 档: 1≤n,x≤100,2≤k≤100 。
- 对于 Hard 档: 1≤n,x≤104,2≤k≤104 。
Output
输出答案模 998 244 353 。
Examples
3 1 2
4
1 1 2
1
4 2 3
4
Note
样例 1:
有四种方案:
- 第一天 1;
- 第一天 2;
- 第一天 3;
- 第一天 1,第二天 2;
注意第一天和第二天都买 1 是不行的,因为连续两天棒棒糖数量一样,baby 就会很不高兴。
POINT:
Dp。
for(int i=1;i<=n-x;i++){ //遍历这一次要买多少
for(int j=x+i;j<=n;j++){ //买完后已经有多少糖果
for(int ii=1;ii<=i;ii++){ //上一次买了多少糖果
如果上一次和这一次买的糖果一样,就特殊处理。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
#define LL long long
const int maxn=111;
const int mod = 998244353;
int dp[maxn][maxn][maxn];
int main()
{
int n,x,k;
scanf("%d %d %d",&n,&x,&k);
if(x>n) {
printf("0\n");
return 0;
}
for(int i=x;i<=n;i++){
dp[i][i][1]=1;
}
for(int i=1;i<=n-x;i++){
for(int j=x+i;j<=n;j++){
for(int ii=1;ii<=i;ii++){
if(ii==i){
for(int p=2;p<k;p++){
(dp[j][i][p]+=dp[j-i][i][p-1])%=mod;
}
}else{
for(int p=1;p<k;p++){
(dp[j][i][1]+=dp[j-i][ii][p])%=mod;
}
}
}
}
}
int ans=0;
for(int i=x;i<=n;i++){
for(int j=1;j<=n;j++){
for(int p=1;p<k;p++){
(ans+=dp[i][j][p])%=mod;
}
}
}
printf("%d\n",ans);
}