题目大意:
给定以字符串,问从中选出任意多个数字可以得到多少不含前导零偶数(可以重复)
分析:
不会数学作法,用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啊