• 【2019.7.6】刷题记录


    1.A+B problem(dp)

    看成完全背包即可。先筛一遍素数,然后枚举素数个数,在枚举价值,dp即可。

    代码:

    #include<cstdio>
    #include<iostream>
    using namespace std;
    int prime[20000];
    int pre[20000],n;
    long long dp[50000];
    inline int solve(int x){
        for(int i=1;i<=x+2000;++i)prime[i]=1;
        for(int i=2;i<=x+2000;++i){
            if(prime[i]){
                for(int j=2*i;j<=x+2000;j+=i){
                    prime[j]=0;
                }
            }
        }int k=0;
        for(int i=2;i<=x+2000;i++)
            if(prime[i])
                pre[++k]=i;
        return k;
    }
    int main(){
        scanf("%d",&n);
        int m=solve(n);
        dp[0]=1;
    //    dp[1]=1;
    //    dp[2]=1;
        for(int i=1;i<=m;++i)
            for(int j=pre[i];j<=n;j++)
                dp[j]+=dp[j-pre[i]];
        printf("%lld
    ",dp[n]);
        return 0;
    } 

    【openjudge9267】(dp求方案数)

    我们设dp[i][0]是第i位不放的方案数,dp[i][1]是第i位放的方案数,则有:

    dp[i][0]=dp[i-1][0]+dp[i-1][1],第i位不放那么前面随便即可

    当i<m时,dp[i][1]=dp[i-1][1]+dp[i-1][0],前面没有限制

    当i=m时,dp[i][1]=dp[i-1][1]+dp[i-1][0]-1,少了一种全部都放的方案

    当i>m时,dp[i][1]=dp[i-1][1]+dp[i-1][0]-dp[i-m][0],若第i位要放,则i-m中必有一位不放,减去其方案数。

    代码:

    #include<cstdio>
    #include<istream>
    using namespace std;
    typedef long long ll;
    ll n,m;
    ll dp[500][10];
    int main(){
        scanf("%lld%lld",&n,&m);
        dp[1][0]=dp[1][1]=1;
        for(ll i=2;i<m;i++){
            dp[i][0]=dp[i-1][0]+dp[i-1][1];
            dp[i][1]=dp[i-1][0]+dp[i-1][1];
        }dp[m][0]=dp[m-1][0]+dp[m-1][1];
        dp[m][1]=dp[m-1][0]+dp[m-1][1]-1;
        for(ll i=m+1;i<=n;i++){
            dp[i][0]=dp[i-1][0]+dp[i-1][1];
            dp[i][1]=dp[i-1][0]+dp[i-1][1]-dp[i-m][0];
        } 
        printf("%lld
    ",dp[n][0]+dp[n][1]);
        return 0;
    }

    【openjudge9272】(数位dp)

    我们设dp[i][1]为i位数奇数个3的数量,dp[i][0]为i位数偶数个3的数量,则:

    #include<cstdio>//数位dp 
    #include<iostream>
    using namespace std;
    const int Hws=12345; 
    int n,dp[1010][2];
    int main(){
        scanf("%d",&n);
        dp[1][1]=1;
        dp[1][0]=9;//1表示1位数,后面的1表示有奇数个0,0则表示有偶数个0
        for(int i=2;i<=n;i++){
            int k=i==n?8:9;//等于n的时候前面不能加0啊 
            dp[i][0]=dp[i-1][0]%Hws*k+dp[i-1][1]%Hws;//第i位有偶数个3可以从i-1位奇数个3补一个3实现 
            dp[i][1]=dp[i-1][1]%Hws*k+dp[i-1][0]%Hws;//也可以在前一位有偶数个3的前面补0,1,2,4,5,6,7,8,9,实现 
        } //第i位有奇数个3同理,但是第n位前面就不能补0了 
        printf("%d
    ",dp[n][0]%Hws);
    }
  • 相关阅读:
    流体力学笔记 第二章 流体力学的基本概念
    jvm常用的参数
    链表的反转
    数据流中的中位数
    二叉树对称
    二叉树镜像
    输入框校验
    判断单选或者复选框中选中的值
    网页中window.open 弹出 父页面和子页面数值交互
    数组去重
  • 原文地址:https://www.cnblogs.com/h-lka/p/11143436.html
Copyright © 2020-2023  润新知