0
点赞
收藏
分享

微信扫一扫

第十三届蓝桥杯省赛b组 两道dp补题

松鼠树屋 2022-04-14 阅读 53
c++

画积木

请添加图片描述
推导见上图
因为画布为2*n,只有两行,所以可以考虑每一种占满两行的方式,对每种方式做一个状态转移,得到的就是总方案数。

#include<bits/stdc++.h>
using namespace std;
const int N=1e7+100;
const int mod=1e9+7;
typedef long long ll;
ll f[N],sum[N];
ll n;
int main(){
    cin>>n;
    f[0]=1;f[1]=1;f[2]=2;
    sum[0]=1;sum[1]=2;sum[2]=4;
    for(int i=3;i<=n;i++){
        f[i]=(f[i]+f[i-1])%mod;
        f[i]=(f[i]+f[i-2])%mod;
        // for(int j=i-3;j>=0;j--){
        //     f[i]=(f[i]+f[j])%mod;
        //     f[i]=(f[i]*2)%mod;
        // }
        f[i]=(f[i]+sum[i-3]+sum[i-3])%mod;
        sum[i]=(sum[i-1]+f[i])%mod;
    }
    cout<<f[n];
    return 0;
}

李白打酒加强版

同上也是一个算方案数的dp。
首先得想到:如果酒的数量比剩下的花的数量还多,那多的酒可以忽略不计
因为每次看见花才喝一壶,那酒大于花,做差剩下的永远也喝不完。
dp[i][j][k]表示走了i次,经过了j个花,还剩下k斗酒。
初始状态 dp[0][0][2]=1计数dp
终止状态 dp[n+m-1][m-1][1] 表示李白差一次走完所有店和花了,走了m-1个花,最后一个是花,最后还剩一斗酒,最后看见花的时候喝。
中间要讨论奇偶性,因为在k为奇数时是不可能是店的,因为店是翻倍,得到的k一定是一个偶数。
在偶数时则是都可以转移,所以在奇数时转移当前为花店,在偶数时转移当前为花店或酒店的情况。

#include<bits/stdc++.h>
using namespace std;
const int N=210;
const int mod=1e9+7;
typedef long long ll;
ll n,m;
ll dp[N][N][N];
int main(){
    cin>>n>>m;
    dp[0][0][2]=1;
    for(int i=1;i<=n+m-1;i++){
        for(int j=0;j<=m-1;j++){
            for(int k=0;k<=m;k++){
                if(k%2==0){
                    dp[i][j][k]=(dp[i][j][k]+dp[i-1][j][k>>1])%mod;
                }
                if(j>=1){
                    dp[i][j][k]=(dp[i][j][k]+dp[i-1][j-1][k+1])%mod;
                }
            }
        }
    }
    cout<<dp[n+m-1][m-1][1]<<endl;
    return 0;
}
举报

相关推荐

0 条评论