Codeforces 31d 题解

题意:给你一个位数为 2 n 2n 的数字 S S ,两个初始为 0 0 的数字 A , B A,B ,每次你可以将 S S 中最靠左的一位在 S S 中删除掉并接在 A A 或者 B B 其中一个的后面,要求整个操作结束后,必须 A A B B 都恰好被接 n n 次,最大化 A + B A+B 的值,输出方案

n 18 n\leq 18

我们考虑线性做法O(n)跑18,我们已经在A和B中放好了S的前i个数,其中A放了j个,B放了k个,那么我们对于第i+1个数,它可以放在A或B的末尾,于是我们有了状态转移方程

f [ i ] [ j ] [ k ] = m a x ( f [ i 1 ] [ j 1 ] [ k ] + s [ i ] 1 0 n j ) , f [ i 1 ] [ j ] [ k 1 ] + s [ i ] 1 0 n k ) f[i][j][k]=max(f[i-1][j-1][k]+s[i]*10^{n-j}),f[i-1][j][k-1]+s[i]*10^{n-k})

放数的时候注意是从最高位开始放

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
#define int long long
using namespace std;
const int N=100;
int n,m,dp[N][N],a[N][N],b[N][N],c[N],len;
char go[N][N][N];
char str[N<<1];
inline int read(){
    int sym=0,res=0;char ch=0;
    while (!isdigit(ch))sym|=(ch=='-'),ch=getchar();
    while (isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
    return sym?-res:res;
}
void file(){
    freopen("read.in","r",stdin);
    freopen("write.out","w",stdout);
}
int power(int a,int x){
    int res=1;
    while (x){
        if (x&1)res*=a;
        a*=a;x>>=1;
    }return res;
}
void write(int now,int x,int y,char ch){
    if (now==0){
        printf("%c",ch);return;
    }
    if (go[now][x][y]=='H')write(now-1,x-1,y,'H');
    else write(now-1,x,y-1,'M');
    if (now!=len)printf("%c",ch);
}
signed main(){
    n=read();len=n<<1;
    scanf("%s",str+1);
    for (int i=1;i<=len;i++){
        c[i]=str[i]-'0';
    }
    for (int i=1;i<=n;i++){
        a[i][i]=a[i-1][i-1]+c[i]*power(10,n-i);go[i][i][0]='H';
        b[i][i]=b[i-1][i-1]+c[i]*power(10,n-i);go[i][0][i]='M';
    }
    for (int i=1;i<=len;i++){
        for (int j=max(i-n,1ll);j<=min(i-1ll,n);j++){
            int k=i-j,ta=c[i]*power(10,n-j),tb=c[i]*power(10,n-k);
            if (a[i-1][j-1]+ta+b[i-1][k]>b[i-1][k-1]+tb+a[i-1][j]){
                a[i][j]=a[i-1][j-1]+ta;
                b[i][k]=b[i-1][k];go[i][j][k]='H';
            }else{
                b[i][k]=b[i-1][k-1]+tb;
                a[i][j]=a[i-1][j];go[i][j][k]='M';
            }
        }
    }
    write(len,n,n,' ');
    return 0;
}
发布了12 篇原创文章 · 获赞 0 · 访问量 116

猜你喜欢

转载自blog.csdn.net/qq_37734034/article/details/104095870
今日推荐