有三种砖 , 要摞成一个Skyscraper ,给出长宽高类似矩形嵌套的部分序关系,根据这个关系给建立DAG图,不过这样要注意一下当砖的类型是0的时候有可能出现环的情况
用并查集维护下就好
#include <cstdio>
#include <cstring>
#define max(a,b) (a>b?a:b)
typedef long long ll;
const int maxn=1050;
int n;
ll a[maxn],b[maxn];
int d[maxn];
ll c[maxn];
ll g[maxn][maxn];
ll dis[maxn];
int ring[maxn];
int find (int x)
{
return ring[x]==x?x:ring[x]=find(ring[x]);
}
void build()
{
memset (g , 0 , sizeof(g));
for (int i=0 ; i<n ; ++i)
ring[i]=i;
for (int i=0 ; i<n ; ++i)
{
for (int j=0 ; j<n ; ++j)
{
if(i==j)continue;
if(d[i]==0)//d=0
{
if(d[j]==0)if(a[i]==a[j] && b[i]==b[j])
{
int fi=find(i);
int fj=find(j);
if(fi==fj)continue;
//g[fi][fj]+=c[j];
c[fi]+=c[j];
ring[fj]=fi;
continue;
}
if(a[i]>=a[j] && b[i]>=b[j])g[i][j]=c[i];
}
if(d[i]==1)
{
if(a[i]>=a[j] && b[i]>=b[j] && a[i]*b[i]>a[j]*b[j])g[i][j]=c[i];
}
if(d[i]==2)
{
if(a[i]>a[j] && b[i]>b[j])g[i][j]=c[i];
}
}
}
}
ll dp(int x)
{
if(dis[x]>0)return dis[x];
ll ans=c[x];
for (int i=0 ; i<n ; ++i)
{
if(ring[i]==i)
if(g[x][i])ans=max(ans,dp(i)+c[x]);
//if(g[i][x])ans=max(ans,dp(i)+g[i][x]);
}
//printf("d[%d]=%d\n",x,dis[x]=ans);
return dis[x]=ans;
}
void debug ()
{
puts("graph:");
for (int i=0 ; i<n ; ++i)
{
for (int j=0 ; j<n ; ++j)
printf("%I64d ",g[i][j]);
puts("");
}
puts("c:");
for (int i=0 ; i<n ; ++i)
printf("%I64d %d~~~ " ,c[i],ring[i]);
puts("");
}
int main ()
{
while (scanf("%d",&n),n)
{
for (int i=0 ; i<n ; ++i)
{
scanf("%I64d%I64d%I64d%d",a+i , b+i , c+i , d+i);
if(a[i]<b[i])a[i]^=b[i]^=a[i]^=b[i];
}
memset (dis , 0 , sizeof(dis));
build();
ll ans=0;
//debug();
for (int i=0 ; i<n ; ++i)
{
if(ring[i]==i)
dis[i]=dp(i);
ans=max(ans,dis[i]);
}
printf("%I64d\n",ans);
}
return 0;
}
HDU 上的类似题1069
数据比较小 用floyd 或DP都行
#include <cstdio>
#include <cstring>
#include <algorithm>
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
using namespace std;
const int maxn=95;
int dp[maxn];
int n;
int l[maxn],w[maxn],h[maxn];
int pin[maxn];
int I=0;
bool cmp(int a,int b)
{
return l[a]>l[b] || (l[a]==l[b] && w[a]>w[b]);
}
int main ()
{
int a,b,c;
while (scanf("%d",&n),n)
{
for (int i=0 ; i<n ; ++i)
{
scanf("%d%d%d",&a,&b,&c);
l[i]=max(a,b);w[i]=min(a,b);dp[i]=h[i]=c;
l[i+n]=max(a,c);w[i+n]=min(a,c);dp[i+n]=h[i+n]=b;
l[i+n+n]=max(b,c);w[i+n+n]=min(b,c);dp[i+n+n]=h[i+n+n]=a;
}
int N=3*n;
for (int i=0 ; i<N ; ++i)
pin[i]=i;
sort (pin , pin+N , cmp);
int ans=0;
//for (int k=0 ; k<N ; ++k)
for (int i=0 ; i<N ; ++i)
{
for (int j=i+1 ; j<N ; ++j)
{
//if(i==j)continue;
if(l[pin[i]]>l[pin[j]] && w[pin[i]]>w[pin[j]])
dp[pin[j]]=max(dp[pin[j]],dp[pin[i]]+h[pin[j]]);
ans=max(ans,dp[pin[j]]);
}
}
/*for (int i=0 ; i<N ; ++i)
printf("%d %d %d %d\n",l[i],w[i],h[i] , dp[i]);*/
printf("Case %d: maximum height = %d\n",++I,ans);
}
return 0;
}