有三種磚 , 要摞成一個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;}