首先上一个非递归的代码 hdu 1520
#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #include<vector> #include<sstream> #include<string> #include<climits> #include<set> #include<bitset> #include<cmath> #include<deque> #include<map> #include<queue> #define iinf 2000000000 #define linf 1000000000000000000LL #define dinf 1e200 #define all(v) (v).begin(),(v).end() #define sz(x) x.size() #define pb push_back #define mp make_pair #define lng long long #define sqr(a) ((a)*(a)) #define pii pair<int,int> #define pll pair<lng,lng> #define pss pair<string,string> #define pdd pair<double,double> #define X first #define Y second #define pi 3.14159265359 #define ff(i,xi,n) for(int i=xi;i<=(int)(n);++i) #define ffd(i,xi,n) for(int i=xi;i>=(int)(n);--i) #define ffl(i,r) for(int i=head[r];i!=-1;i=edge[i].next) #define cc(i,j) memset(i,j,sizeof(i)) #define N 111111 #define M 222222 using namespace std; typedef vector<int> vi; typedef vector<string> vs; typedef unsigned int uint; typedef unsigned lng ulng; template<class T> inline void checkmax(T &x,T y){if(x<y) x=y;} template<class T> inline void checkmin(T &x,T y){if(x>y) x=y;} template<class T> inline T Min(T x,T y){return (x>y?y:x);} template<class T> inline T Max(T x,T y){return (x<y?y:x);} template<class T> T gcd(T a,T b){return (a%b)==0?b:gcd(b,a%b);} template<class T> T lcm(T a,T b){return a*b/gcd(a,b);} struct pp{int v,w,next;}edge[10*M];int tot=0,root,head[N],n,m,cost[N],dp[N][2];bool is[N]; inline void addedge(int u,int v,int w,int *h){edge[tot].v=v,edge[tot].w=w,edge[tot].next=h[u],h[u]=tot++;} int r[2222222],to[2222222]; int v; void dfs() { int tp=0; r[++tp]=root;to[tp]=head[root]; L:; dp[r[tp]][0]=0,dp[r[tp]][1]=cost[r[tp]]; for(;to[tp]!=-1;to[tp]=edge[to[tp]].next) { r[tp+1]=edge[to[tp]].v,to[tp+1]=head[edge[to[tp]].v]; tp++; goto L; Z:; dp[r[tp]][0]+=Max(dp[edge[to[tp]].v][0],dp[edge[to[tp]].v][1]); dp[r[tp]][1]+=dp[edge[to[tp]].v][0]; } --tp; if(tp) goto Z; } int main() { #ifdef DEBUG // freopen("data.in","r",stdin); // freopen("data.out","w",stdout); #endif while(scanf("%d",&n)==1) { tot=0;cc(head,-1);ff(i,1,n) scanf("%d",cost+i);cc(is,0); ff(i,2,10000000){int u,v;scanf("%d%d",&u,&v);if(u==0&&v==0) break;addedge(v,u,0,head);is[u]=1;} ff(i,1,n) if(!is[i]){root=i;break;} dfs(); printf("%d\n",dp[root][1]>dp[root][0]?dp[root][1]:dp[root][0]); } return 0; } /* made by qinggege */
看上面的程序不难总结出这样的模板
1:L;; 执行操作
2:剪枝判断 如果可以剪掉 直接转到4
3:进行出口往下进行 留下标记Z;;
4:弹出当前 如果还有 则跳转到Z;
其中值得注意的是在第三步 存储的位置信息要不停的更新,每次的操作对象都是栈的头,跳出的条件只有剪枝的判断,还有出口全部进行完毕的情况
附上上次面试题的非递归模板版本
#include<cstring> #include<cstdio> #include<cmath> #include<cstdlib> #include<iostream> using namespace std; double a[2000002]; int n; template<class T> void quicksort(T *p,int s,int e) { if(s<e) { int i=s,j=e;T tmp=p[e]; while(i<j) { while(i<j&&p[i]<tmp) ++i; if(i<j) p[j--]=p[i]; while(i<j&&p[j]>tmp) --j; if(i<j) p[i++]=p[j]; } p[i]=tmp; quicksort(p,s,i-1); quicksort(p,i+1,e); } } double res=0; double sum[2000002]; double ss; int k[2000000],id[20000000]; int f[22222222]; double now[20000000]; int top=0; void dfs() { k[++top]=0,id[top]=1,now[top]=0;f[top]=0; L:; // cout<<k[top]<<" "<<now[top]<<" "<<id[top]<<" "<<f[top]<<endl; if(k[top]==n&&res<now[top]) res=now[top]; if(k[top]==n||id[top]==2*n+1||2*n-id[top]+1<n-k[top]||sum[id[top]+n-k[top]-1]-sum[id[top]-1]+now[top]>ss||sum[id[top]+n-k[top]-1]-sum[id[top]-1]+now[top]<=res) { goto Z;} for(;f[top]<2;){ if(f[top]==0){ k[top+1]=k[top]+1,now[top+1]=now[top]+a[id[top]],id[top+1]=id[top]+1,f[top+1]=0;top++;goto L;} else {k[top+1]=k[top],now[top+1]=now[top],id[top+1]=id[top]+1,f[top+1]=0;top++;goto L;} S:;f[top]++; } Z:; top--;if(top) goto S; } int main() { freopen("data.txt","r",stdin); // freopen("data1.txt","w",stdout); cin>>n; n=40000; for(int i=1;i<=2*n;++i) { scanf("%lf",&a[i]); // printf("%d %lf\n",i,a[i]); } quicksort(a,1,2*n); sum[0]=0; for(int i=1;i<=2*n;++i) {sum[i]=sum[i-1]+a[i];} ss=sum[2*n]/2; dfs(); printf("%lf %lf %lf\n",res,sum[2*n],ss); printf("%lf\n",sum[2*n]-2*res); return 0; }