[CF31E]TV Game

31E:TV Game

題意簡述

給出一個長度爲2n 的數列s
要形成兩個長度爲n 的數列a,b ,每次你可以從s 的最左邊取出一個數,接到ab 後面。
要使得a+b 的和最大,輸出一個取數的方案。

思路

先把s 倒序,這樣我們加數變成了往最高位上加。
這樣有什麼好處呢…方便了轉移,因爲答案是兩個數的和。
如果正着轉移的話,要同時記錄兩個數?非常麻煩。
f[i][j] 表示a 取了i 個,b 取了j 個的最大值。
f[i][j]=max(f[i1][j]+s[i+j1]10i1,f[i][j1]+s[i+j1]10j1)
時間複雜度O(n2)

代碼

#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
long long ans;
int n,cnt;
char pre[20][20],ansf[40],st[40];
long long f[20][20],pow10[20];
int main()
{
    scanf("%d",&n);
    scanf("%s",st);
    reverse(st,st+n*2);
    pow10[0]=1;
    for (int i=1;i<=n;i++)
        pow10[i]=pow10[i-1]*10;
    for (int i=0;i<=n;i++)
        for (int j=0;j<=n;j++)
        {
            if (f[i][j]+pow10[i]*(st[i+j]-'0')>=f[i+1][j])
            {
                f[i+1][j]=f[i][j]+pow10[i]*(st[i+j]-'0');
                pre[i+1][j]='H';
            }
            if (f[i][j]+pow10[j]*(st[i+j]-'0')>=f[i][j+1])
            {
                f[i][j+1]=f[i][j]+pow10[j]*(st[i+j]-'0');
                pre[i][j+1]='M';
            }
        }
    int x=n,y=n;
    while (x||y)
    {
        if (pre[x][y]=='H')
        {
            ansf[++cnt]='H';
            x--;
        }
        else
        {
            ansf[++cnt]='M';
            y--;
        }
    }
    for (int i=1;i<=cnt;i++)
        printf("%c",ansf[i]);
    return 0;
}
發佈了53 篇原創文章 · 獲贊 38 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章