CDE题

C题:构造

#include<bits/stdc++.h>
using namespace std;

void put0(int x)
{
    while(x>0)cout<<0,x--;
}

void put1(int x)
{
    while(x>0)cout<<1,x--;
}

void put01(int x)
{
    while(x>0)cout<<0<<1,x--;
}

void solved()
{
    int a,b,k;cin>>a>>b>>k;
    
    if(k==0)
    {
        if(a && b)cout<<-1;
        else put0(a),put1(b);
    }
    else
    {
        if(a==b && k>min(a,b)*2-1)cout<<-1;
        else if(a!=b && k>min(a,b)*2)cout<<-1;
        else
        {
            if(k&1)//奇数
            {
                int d=(k+1)/2;
                put0(a-d),put01(d),put1(b-d);
            }
            else//偶数
            {
                int d=k/2;
                if(a>=b)put0(a-d-1),put01(d),put1(b-d),put0(1);
                else put1(1),put0(a-d),put01(d),put1(b-d-1);
            }
        }
    }
    cout<<'\n';
}

int main()
{
    int t;
    cin>>t;
    while(t--)solved();
	return 0;
}

D题法一:dp,直接顺推就行

#include<bits/stdc++.h>
#define int long long
using namespace std;

void solved()
{
    int n,x,y;cin>>n>>x>>y;
    string s;cin>>s;s=" "+s;
    vector<int> f(n+1,1e18),ne0(n+1),ne1(n+1);
    
    //ne0[i],ne1[i]分别表示i位置右边最近的0和1的位置
    int p0=0,p1=0;
    for(int i=n;i>=1;i--)//预处理ne0[i],ne1[i]
    {
        ne0[i]=p0,ne1[i]=p1;
        s[i]=='1'?p1=i:p0=i;
    }
    
    f[1]=0;
    for(int i=1;i<=n;i++)//顺序递推即可
    {
        if(ne1[i])f[ne1[i]]=min(f[ne1[i]],f[i]+(s[i]=='1'?x:y));
        if(ne0[i])f[ne0[i]]=min(f[ne0[i]],f[i]+(s[i]=='0'?x:y));
    }
    cout<<f[n];
}

signed main()
{
    solved();
	return 0;
}

D题法二:Dijkstra求单源最短路

#include<bits/stdc++.h>
#define int long long
using namespace std;

using PII=pair<int,int>;

void solved()
{
    int n,x,y;cin>>n>>x>>y;
    string s;cin>>s;s=" "+s;
    
    vector<int> ne0(n+1),ne1(n+1);
    //ne0[i],ne1[i]分别表示i位置右边最近的0和1的位置
    int p0=0,p1=0;
    for(int i=n;i>=1;i--)//预处理ne0[i],ne1[i]
    {
        ne0[i]=p0,ne1[i]=p1;
        s[i]=='1'?p1=i:p0=i;
    }
    
    //Dijkstra求单源最短路
    vector<int> f(n+1,1e18),vis(n+1,0);
    priority_queue<PII,vector<PII>,greater<PII>> q;
    q.push({0,1});f[1]=0;
    
    while(q.size())
    {
        auto[cost,t]=q.top();q.pop();
        
        if(vis[t])continue;
        vis[t]=1;
        
        int x0=ne0[t],x1=ne1[t];
        if(x0)
        {
            int d=(s[t]=='0'?x:y);
            if(cost+d<f[x0])
            {
                f[x0]=cost+d;
                q.push({f[x0],x0});
            }
        }
        if(x1)
        {
            int d=(s[t]=='1'?x:y);
            if(cost+d<f[x1])
            {
                f[x1]=cost+d;
                q.push({f[x1],x1});
            }
        }
    }
    cout<<f[n];
}

signed main()
{
    solved();
	return 0;
}

E题:dp,跟D题一样直接顺推就行

#include<bits/stdc++.h>
#define int long long
using namespace std;

const int mod=1e9+7;

void solved()
{
	string s;cin>>s;
	int n=s.size();s=" "+s;
	
	//f[i][j]:前i个组成的整数模13余j的方案数 
	vector<vector<int>> f(n+1,vector<int> (13));
	
	f[0][0]=1;//初值 
	for(int i=1;i<=n;i++)
	{
		if(s[i]=='?')
		{
			for(int j=0;j<13;j++)//?有两种情况:即可能是1也可能是0 
			{
				f[i][(j*10)%13]+=f[i-1][j]; 
				f[i][(j*10)%13]%=mod;
				f[i][(j*10+1)%13]+=f[i-1][j]; 
				f[i][(j*10+1)%13]%=mod;
			}
		}
		else
		{
			for(int j=0;j<13;j++)
			{
				f[i][(j*10+s[i]-'0')%13]+=f[i-1][j]; 
				f[i][(j*10+s[i]-'0')%13]%=mod;
			}
		}
	}
	cout<<f[n][0];//答案:前n个数组成的整数%13等于0的方案数 
}

signed main()
{
    solved();
	return 0;
}