DAG 动态规划 巴比伦塔 B - The Tower of Babylon

时间:2023-03-08 21:37:18
DAG 动态规划 巴比伦塔 B - The Tower of Babylon

题目: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=,int y=,int z=) : x(x) , y(y) , z(z){}
}exa[];
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[]; int main()
{
int num=;
while(scanf("%d",&n)==&&n)
{
memset(dp,,sizeof(dp));
for(int i=;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*+i]=node(b,a,c);
exa[n*+i]=node(a,c,b);
exa[n*+i]=node(c,a,b);
exa[n*+i]=node(c,b,a);
}
n*=;
int ans=;
sort(exa+,exa+n+,cmp);
for(int i=;i<=n;i++)
{
dp[i]=exa[i].z;
for(int j=;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 ;
}