[POJ2161]Chandelier
题目大意:某个坑爷的公司要组装灯具,给出一个len≤10000的序列来描述这个灯具。a表示将一个灯泡放到栈中,X=1~9的一个数字表示将栈顶X个元素取出按顺序组装成一个环形的新元素。栈的大小为同时存在于栈中最多的元素的个数,求组装完这个灯具所需的最小的栈的大小并输出安装序列。
题目补充:按顺序组 装的意思就是说 某个环形= i1 i2 i3 i4, 你可以按照 <i1 i2 i3 i4>或<i2 i3 i4 i1>或<i3 i4 i1 i2>或<i4 i1 i2 i3>的顺序组装(从环上任意一点为起点组装)
题解:毫无疑问的纯模拟,也就看起来烦,其实还是很短的。遇到这种题目不可掉以轻心忽略极端情况,也不能畏首畏尾不敢动手。
#include<cstdio>
#include<cstring>
#include<iostream>
const int INF=~0U>>1;
using namespace std;
#define N 10001
int n,pos,cal[N],len[N],s[N],queue[N][10];
char ins[N];
int dfs(){
int i,j,u=pos--,v,tab[10],t;
if(ins[u]=='a') len[u]=cal[u]=1;
else{
len[u]=ins[u]-'0';
for(i=len[u]-1;i>=0;i--){
queue[u][i]=pos;
tab[i]=dfs();
}
cal[u]=INF;
for(i=0;i<len[u];i++){
v=t=0;
for(j=i;j<i+len[u];j++){
v=max(v,t+tab[j%len[u]]);
t++;
}
if(v<cal[u]){
s[u]=i;
cal[u]=v;
}
}
}
return cal[u];
}
void print(int u){
if(ins[u]=='a') printf("a");
else{
for(int i=s[u];i<s[u]+len[u];i++){
print(queue[u][i%len[u]]);
}
printf("%d",len[u]);
}
}
int main(){
freopen("mock.in","r",stdin);
freopen("mock.out","w",stdout);
cin>>ins;
n=strlen(ins);
pos=n-1;
printf("%d\n",dfs());
print(n-1);
return 0;
}