有三种砖 , 要摞成一个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; }