Bingbong的奇偶世界

题目链接在这里

题目大意:
给定以字符串,问从中选出任意多个数字可以得到多少不含前导零偶数(可以重复)

分析:
不会数学作法,用dp思维
dp[i][1] 表示[1…9]xxx 前ii个数字不含前导零的数字个数(至少两位起步,单独处理一位数)
dp[i][2] 表示前i个数字不含前导零偶数的个数

if(当前位是0){
dp[i-1][1]会对dp[i][1]有贡献
dp[i-1][1]会对dp[i][2]有贡献:任意数字添上一个偶数就变成偶数了
}else{
dp[i][1]+1(相当于选第一个数,不能有前导零)
dp[i-1][1]会对dp[i][1]有贡献
if(当前为是偶数){
dp[i-1][1]会对dp[i][2]有贡献:任意数字添上一个偶数就变成偶数
}
}

特殊处理只有1为数的情况
最后答案为ans+dp[n][2]

#include<bits/stdc++.h>
using namespace std;
using i64 = long long;
#define ios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);

const int mod = 1e9+7;
int n;
string s;
i64 ans;
i64 dp[200010][3];
//dp[i][0] [1..9]xxx
//dp[i][1] [1...9]xxxx[0,2,4,6,8]
signed main(){
    ios;
    cin>>n>>s;
    s = ' '+s;
    vector<int>a(n+1);
    for(int i = 1;i<=n;++i){
        a[i] = s[i]-'0';
        ans+=((s[i]-'0')%2==0);
    }
    for(int i = 1;i<=n;++i){
        dp[i][1] = dp[i-1][1];
        dp[i][2] = dp[i-1][2];
        if(a[i]==0){
            dp[i][1] = (dp[i][1]+dp[i-1][1])%mod;
            dp[i][2] = (dp[i][2]+dp[i-1][1])%mod;
        }else{
            dp[i][1] = (dp[i][1]+1LL)%mod;
            dp[i][1] = (dp[i][1]+dp[i-1][1])%mod;
            if(a[i]%2==0){
                dp[i][2] = (dp[i][2]+dp[i-1][1])%mod;
            }
        }
    }
    cout<<(ans+dp[n][2])%mod<<"\n";
    return 0;
}

蒟蒻好想会dp啊

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值