【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);
}
原文地址:https://www.cnblogs.com/h-lka/p/11143436.html