dp小计9.23

Problem - G - Codeforces

核心就是看 是要左边的还是要右边的。

在看左边的时候,直接就加上左边。

在看右边的时候,左边的情况 有两种,一种是已经加了,一种是没有加。然后再加右边自己的。

#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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值