DAG 动态规划 巴比伦塔 B - The Tower of Babylon
这是一个DAG 模型,有两种常规解法
1.记忆化搜索, 写函数,去查找上一个符合的值,不断递归
2.递推法
方法一:记忆化搜索 #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> using namespace std; struct node { int x,y,z; node(int x=0,int y=0,int z=0) : x(x) , y(y) , z(z){} }exa[5000]; bool cmp(node a,node b) { if(a.x==b.x) return a.y>b.y; else return a.x>b.x; } int n; int dp[10000]; bool vis[10000]; int d(int e) { if(vis[e]) return dp[e]; vis[e]=1; int &ans=dp[e]; ans=exa[e].z; for(int i=1;i<e;i++) { // printf("exa[%d].x=%d\n",i,exa[i].x); // printf("exa[%d].y=%d\n",i,exa[i].y); // printf("exa[%d].x=%d\n",e,exa[e].x); // printf("exa[%d].y=%d\n",e,exa[e].y); if(exa[i].x>exa[e].x&&exa[i].y>exa[e].y) { ans=max(ans,d(i)+exa[e].z); // cout<<ans<<" "<<i<<endl; } } return ans; } int main() { int num=0; while(scanf("%d",&n)==1&&n) { memset(dp,0,sizeof(dp)); memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); exa[i]=node(a,b,c); exa[n+i]=node(b,c,a); exa[n*2+i]=node(b,a,c); exa[n*3+i]=node(a,c,b); exa[n*4+i]=node(c,a,b); exa[n*5+i]=node(c,b,a); } n*=6; sort(exa+1,exa+n+1,cmp); int ans=0; for(int i=1;i<=n;i++) { int tmp=d(i); ans=max(ans,tmp); } printf("Case %d: maximum height = %d\n",++num,ans); } return 0; }
方法二:递推法 #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> using namespace std; struct node { int x,y,z; node(int x=0,int y=0,int z=0) : x(x) , y(y) , z(z){} }exa[500]; bool cmp(node a,node b) { if(a.x==b.x) return a.y>b.y; else return a.x>b.x; } int n; int dp[1000]; int main() { int num=0; while(scanf("%d",&n)==1&&n) { memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); exa[i]=node(a,b,c); exa[n+i]=node(b,c,a); exa[n*2+i]=node(b,a,c); exa[n*3+i]=node(a,c,b); exa[n*4+i]=node(c,a,b); exa[n*5+i]=node(c,b,a); } n*=6; int ans=0; sort(exa+1,exa+n+1,cmp); for(int i=1;i<=n;i++) { dp[i]=exa[i].z; for(int j=1;j<i;j++) { if(exa[i].x<exa[j].x&&exa[i].y<exa[j].y) { dp[i]=max(dp[i],dp[j]+exa[i].z); //cout<<dp[i]<<"ww "<<i<<endl; }//cout<<dp[i]<<" "<<i<<endl; } ans=max(ans,dp[i]); } printf("Case %d: maximum height = ",++num); cout<<ans<<endl; } return 0; }