题目链接:
http://poj.org/problem?id=1239
Increasing Sequences
Memory Limit: 10000K
题解
dp两遍,第一遍从前往后求最后一个数的最小值,第二遍从后往前,构造前面大的解。
代码
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII;
const int INF=0x3f3f3f3f;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-8;
const double PI = acos(-1.0);
//start----------------------------------------------------------------------
const int maxn=88;
char str[maxn];
///dp:从前扫,dp2从后扫
int dp[maxn],dp2[maxn];
///val保存切出来的字符串(不包含前导0),val2包含前导零。
string val[maxn],val2[maxn];
int n;
vector<string> ans;
void print(int i) {
if(i==n+1) return;
ans.pb(val2[i]);
print(dp2[i]);
}
int main() {
while(scanf("%s",str+1)==1) {
ans.clear();
if(strlen(str+1)==1&&str[1]=='0') break;
n=strlen(str+1);
///val[0]不能为“0”!!
///从前扫
dp[0]=0,val[0]="";
for(int i=1; i<=n; i++) {
for(int j=i; j>=1; j--) {
string tmp,tmp2;
for(int k=j; k<=i; k++) {
tmp2+=str[k];
if(tmp.length()==0&&str[k]=='0') continue;
tmp+=str[k];
}
if(tmp.length()==0) tmp+="0";
if(tmp.length()>val[j-1].length()||tmp.length()==val[j-1].length()&&tmp>val[j-1]) {
val[i]=tmp;
val2[i]=tmp2;
dp[i]=j-1;
break;
}
}
}
///从后扫
clr(dp2,-1);
int st=dp[n]+1;
dp2[st]=n+1,val[st]=val[n],val2[st]=val2[n];
for(int i=st-1; i>=1; i--) {
if(str[i]=='0'){
///前导零特殊处理
dp2[i]=dp2[i+1];
val[i]=val[i+1];
val2[i]="0"+val2[i+1];
continue;
}
for(int j=st-1; j>=i; j--) {
if(dp2[j+1]<0) continue;
string tmp,tmp2;
for(int k=i; k<=j; k++) {
tmp2+=str[k];
if(tmp.length()==0&&str[k]=='0') continue;
tmp+=str[k];
}
if(tmp.length()==0) tmp+="0";
if(tmp.length()<val[j+1].length()||tmp.length()==val[j+1].length()&&tmp<val[j+1]) {
val[i]=tmp;
val2[i]=tmp2;
dp2[i]=j+1;
break;
}
}
}
print(1);
rep(i,0,ans.sz()){
prf("%s",ans[i].c_str());
if(i==ans.sz()-1) prf("
");
else prf(",");
}
}
return 0;
}