简单的类LIS问题,按长和宽排序然后DP。注意两个问题即可,一是要规定长的边为长,短边为宽,二是排序时要将要求较少的块放在后面。
#include <stdio.h> #include <string.h> #include <algorithm> #define MAXN 1005 typedef __int64 LL; struct block{ int ai,bi,ci,di; bool operator <(const block& b)const{ if(ai!=b.ai)return ai<b.ai; if(bi!=b.bi)return bi<b.bi; return di>b.di; } }b[MAXN]; int n; LL d[MAXN],ans; int main(){ while(scanf("%d",&n),n){ for(int i=0;i<n;i++){ scanf("%d%d%d%d",&b[i].ai,&b[i].bi,&b[i].ci,&b[i].di); if(b[i].ai<b[i].bi)std::swap(b[i].ai,b[i].bi); } std::sort(b,b+n); ans=0; for(int i=0;i<n;i++){ d[i]=b[i].ci; for(int j=0;j<i;j++){ if(b[i].di==1&&b[i].ai*b[i].bi==b[j].ai*b[j].bi)continue; if(b[i].di==2&&(b[i].ai==b[j].ai||b[i].bi==b[j].bi))continue; if(b[i].bi>=b[j].bi&&b[i].ai>=b[j].ai&&d[j]+b[i].ci>d[i]){ d[i]=d[j]+b[i].ci; } } if(d[i]>ans)ans=d[i]; } printf("%I64d\n",ans); } }