zoukankan      html  css  js  c++  java
  • E比昨天更多的棒棒糖(Easy+Hrad)(华师网络赛)(DP||母函数||背包优化)

    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 就会很不高兴。

    题意:

    把n表示成a1*p1+a2*p2+a3*p3...的形式,且满足x<=a1<a2<a3..;0<p<K;

    自己思路:

    数的划分问题。

    小数据,可以用DP或者母函数来解决,可以参考官方题解,这里不再累赘。

    官方题解:

    (ORZ,母函数优化背包)

     Easy版本,普通母函数

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<memory.h>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int Mod=998244353;
    int c1[330],c2[330],ans,x,K,p;
    int n,i,j,m,k;
    void _get()
    {  
        memset(c1,0,sizeof(c1));
        memset(c2,0,sizeof(c2));
        scanf("%d%d",&x,&K);
        for(k=0;k<K&&k*x<=n;k++) {
             c1[k*x]=1;
             ans=(ans+c1[k*x])%Mod;
        }
        for(i=x+1;i<=n;i++){
            for(j=0;j<=n;j++)
              for(k=0;k*i+j<=n&&k<K;k++) {
                   c2[k*i+j]+=c1[j]; 
                   if(k) ans=(ans+c1[j])%Mod;
                }
            for(k=0;k<=n;k++) {
                c1[k]=c2[k];    
                c2[k]=0;
            }
        }
        ans=(ans+Mod-1)%Mod;
    }
    int main()
    {
      
        while(cin>>n) {
            ans=0;
            _get(); 
            cout<<ans<<endl;
        }
        return 0;
    }

    Hard版本,母函数优化背包。

    左边的用a表示,右边的用b表示。 左边和右边分别是背包问题。

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<cstring>
    using namespace std;
    const int Mod=998244353;
    const int maxn=10100;
    long long  a[maxn],b[maxn],c[maxn],ans;
    int main()
    {
        int n,x,k,i,j;
        scanf("%d%d%d",&n,&x,&k);
        a[0]=b[0]=1;
        
        for(i=x;i<=n;i++)
         for(j=n;j>=0;j--)
          if(j>=i*k) a[j]=(a[j]-a[j-i*k])%Mod;
          
        for(i=x;i<=n;i++)
         for(j=i;j<=n;j++)
           b[j]=(b[j]+b[j-i])%Mod;
        
        for(i=0;i<=n;i++)
         for(j=0;j<=n;j++)
          if(i+j<=n) c[i+j]=(c[i+j]+a[i]*b[j])%Mod;
    
         for(i=1;i<=n;i++)
           ans=((ans+c[i])%Mod+Mod)%Mod;
         
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    内网穿透(Frp)-拯救没有公网IP的你
    用Windows远程桌面连接树莓派的方法
    TensorFlow 1.9开始支持树莓派
    树莓派制作遥控小车-新手教程
    Layui 一个页面包含多个table时不展示分页条
    MVC 通过@符号把数据赋值给jQuery对象
    jQuery 批量为表单元素赋值
    layui分页组件,一直在调用方法的解决办法
    layui 表格复选框不居中解决办法
    JQuery 解决遮罩层下内容可以滚动问题
  • 原文地址:https://www.cnblogs.com/hua-dong/p/8011232.html
Copyright © 2011-2022 走看看