EOJ Monthly 2017.12

来源:互联网 发布:淘宝阿迪达斯旗舰店 编辑:程序博客网 时间:2024/05/16 15:28
E1. 比昨天更多的棒棒糖 (Easy)

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 档:1n,x100,2k100
  • 对于 Hard 档:1n,x104,2k104

Output

输出答案模 998 244 353

Examples

input
3 1 2
output
4
input
1 1 2
output
1
input
4 2 3
output
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 longconst 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);}



原创粉丝点击