核心就是看 是要左边的还是要右边的。
在看左边的时候,直接就加上左边。
在看右边的时候,左边的情况 有两种,一种是已经加了,一种是没有加。然后再加右边自己的。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int m=1e9+7;
int dp[3000000][3];
int l[5000000];
int r[5000000];
void solve()
{
string s;
cin>>s;
int ans=0;
int n=s.size();
s=" "+s;
int cnt=0;
for(int i=0;i<=n;i++)
{
dp[i][0]=dp[i][1]=0;
}
for(int i=1;i<=n;i++)
{
if(s[i]=='A') cnt++;
else l[i]=cnt,cnt=0;
}
cnt=0;
for(int i=n;i;i--)
{
if(s[i]=='A') cnt++;
else r[i]=cnt,cnt=0;
}
vector<int>f(1,0);
for(int i=1;i<=n;i++)
{
if(s[i]=='B') f.push_back(i);
}
for(int i=1;i<f.size();i++)
{
//if(s[f[i]]=='A') continue;
dp[f[i]][0]=dp[f[i-1]][0]+l[f[i]];
dp[f[i]][1]=max(dp[f[i-1]][0],dp[f[i-1]][1])+r[f[i]];
ans=max(dp[f[i]][0],dp[f[i]][1]);
}
cout<<ans<<endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T;
cin>>T;
while(T--)
{
solve();
}
}
2023 NENUACM校队训练#19 - Virtual Judge (vjudge.net)
去统计每个字符的数量之后,看具体的情况。如果是奇数情况,这个可以选择删或者不删。
如果是偶数情况,这个不删,那么上一个必须删,这个删了,那么上个可以删也可以不删,选择个最小的就行。然后加上当下的情况。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int MAXN=1e6+10;
int dp[MAXN][5];
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;
cin>>n;
vector<int>a;
vector<int>b(MAXN);
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
b[x]++;
}
for(int i=1;i<=MAXN;i++){
if(i%2==0)
{
dp[i][0]=dp[i/2][1];
dp[i][1]=min(dp[i/2][0],dp[i/2][1])+b[i];
}
else{
dp[i][0]=0;
dp[i][1]=b[i];
}
}
int sum=0;
for(int i=1e6;2*i>1e6;i--)
{
sum+=min(dp[i][0],dp[i][1]);
}
cout<<sum<<endl;
}
icpc网络赛的一个dp题:
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5+10;
const int mod = 998244353;
int dp[2][63][8];
int pos[63];
map<char,int> mp;
signed main() {
int n;cin>>n;
string s;cin>>s;
for(int i=1;i<=26;i++) pos[i]=0;
for(int i=27;i<=52;i++) pos[i]=1;
for(int i=53;i<=62;i++) pos[i]=2;
for(int i=0;i<26;i++) {
mp['a'+i]=i+1;
}
for(int i=0;i<26;i++) {
mp['A'+i] = i+1+26;
}
for(int i=0;i<10;i++) {
mp['0'+i] = i+1+52;
}
char a=s[0];
if(a=='?') {
for(int i=1;i<=62;i++) {
dp[1][i][1<<pos[i]] = 1;
}
} else if(a>='0'&&a<='9') {
dp[1][mp[a]][1<<pos[mp[a]]] = 1;
} else if(a>='a'&&a<='z') {
dp[1][mp[a]][1<<pos[mp[a]]] = 1;
int id=mp[a]+26;
dp[1][id][1<<pos[id]] = 1;
} else {
dp[1][mp[a]][1<<pos[mp[a]]] = 1;
}
for(int i=2;i<=n;i++) {
char c = s[i-1];
for(int j=1;j<=62;j++) for(int x=0;x<=7;x++) dp[i&1][j][x]=0;
if((c>='0'&&c<='9') ||(c>='A'&&c<='Z')){
int id;
if(c>='0'&&c<='9') id=52+c-'0'+1;
if(c>='A'&&c<='Z') id=26+c-'A'+1;
for(int j=1;j<=62;j++) {
if(j==id) continue;
for(int k=0;k<=7;k++) {
dp[i&1][id][k|(1<<pos[id])] += dp[(i-1)&1][j][k];
dp[i&1][id][k|(1<<pos[id])] = dp[i&1][id][k|(1<<pos[id])]%mod;
}
}
} else if(c>='a'&&c<='z') {
int id=c-'a'+1;
for(int j=1;j<=62;j++) {
if(j==id) continue;
for(int k=0;k<=7;k++) {
dp[i&1][id][k|(1<<pos[id])] += dp[i-1&1][j][k];
dp[i&1][id][k|(1<<pos[id])] = dp[i&1][id][k|(1<<pos[id])] % mod;
}
}
id+=26;
for(int j=1;j<=62;j++) {
if(j==id) continue;
for(int k=0;k<=7;k++) {
dp[i&1][id][k|(1<<pos[id])] += dp[i-1&1][j][k];
dp[i&1][id][k|(1<<pos[id])] = dp[i&1][id][k|(1<<pos[id])] % mod;
}
}
} else {
vector<int> v;
for(int x=0;x<=7;x++) {
int ans=0;
for(int j=1;j<=62;j++) {
ans=ans+dp[i-1&1][j][x];
ans = ans % mod;
}
v.push_back(ans);
}
for(int j=1;j<=62;j++) {
for(int x=0;x<=7;x++) {
dp[i&1][j][x|(1<<pos[j])] += (v[x]-dp[i-1&1][j][x]+mod)%mod;
dp[i&1][j][x|(1<<pos[j])] = (dp[i&1][j][x|(1<<pos[j])]+mod )%mod;
}
}
}
}
int ans=0;
for(int i=1;i<=62;i++) ans=(ans+dp[n&1][i][7])%mod;
cout<<ans<<endl;
}