小六喜欢两全其美的事情,今天就正好有一个这样的机会。
小六面前有两根管子,管子里面放满了数字为1到9的小球。每次取球时,小六会先选择一根管子,再从这根管子的某一侧(左侧或右侧)取出一个球。在满足取球规则的情况下,他可以任意顺序取出所有小球。假如小六依次取出的球的编号为,则他最后就得到了一个形如样的十进制数。
小六希望他的取球顺序所组成的数是最大的,你可以帮一下他吗?
思路:
四维记忆化搜索
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define ll long long
#define inf 0x3f3f3f3f
#define rep(i,a,b) for(register int i=(a);i<=(b);++i)
using namespace std;
const int maxn=45;
int n,m,k;
int a[maxn],sum[maxn];
int c[maxn];
int ans,ct,cnt,tmp,flag;
char s[maxn],ss[maxn];
string dp[42][42][42][42];
void cal(string &str,string str2)
{
if(str<str2) str=str2;
return ;
}
string dfs(int x,int y,int xx,int yy,string str)
{
if(x>y&&xx>yy) return str;
if(dp[x][y][xx][yy]!="*") return dp[x][y][xx][yy];
char ch='0';
string st="",st1="",st2="";
if(x<=y) ch=max(s[x],max(ch,s[y]));
if(xx<=yy) ch=max(ss[xx],max(ch,ss[yy]));
st2+=ch;
//cout<<st2<<endl;
if(x<=y&&s[x]==ch) cal(st1,dfs(x+1,y,xx,yy,st));
if(x<=y&&s[y]==ch) cal(st1,dfs(x,y-1,xx,yy,st));
if(xx<=yy&&ss[xx]==ch) cal(st1,dfs(x,y,xx+1,yy,st));
if(xx<=yy&&ss[yy]==ch) cal(st1,dfs(x,y,xx,yy-1,st));
if(dp[x][y][xx][yy]=="*")
dp[x][y][xx][yy]=st2+st1;
//cout<<st2+st1<<endl;
return dp[x][y][xx][yy];
}
int main()
{
int T,cas=1;
scanf("%d",&T);
while(T--)
{
scanf("%s %s",s+1,ss+1);
int l1=strlen(s+1),l2=strlen(ss+1);
rep(i,0,l1)
rep(ii,0,l1)
rep(j,0,l2)
rep(jj,0,l2)
dp[i][ii][j][jj]="*";
string s2="";
string str=dfs(1,l1,1,l2,s2);
printf("Case #%d: %s\n",cas++,str.c_str());
}
return 0;
}