31E:TV Game
题意简述
给出一个长度为
2n
的数列
s
。
要形成两个长度为
要使得
思路
先把
s
倒序,这样我们加数变成了往最高位上加。
这样有什么好处呢…方便了转移,因为答案是两个数的和。
如果正着转移的话,要同时记录两个数?非常麻烦。
f[i][j]=max(f[i−1][j]+s[i+j−1]∗10i−1,f[i][j−1]+s[i+j−1]∗10j−1)
时间复杂度
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;
}