题目勉强可以算是一个DP题目把,贪心部分很好想到,题意是 给你k个n维的 盒子,如果一个盒子的相应的每一维都比另一个盒子的每一维大,就代表这个盒子包含另一个盒子,问给你的k个盒子中最多几个盒子连续包含,而且每一维的位置并不是固定的,是可以自己排序调整的,那么直接应用贪心思想全部从小到大或者从大到小都是可以的,接下来 就是一个 DFS过程了,每找到一个盒子 他能包含另一个盒子时,再往下一层进行寻找,找另一个盒子下面包含的,找到深度最深的那个就是最大连续包含量,同时利用深搜记录下,是哪几个盒子
#include<iostream> #include<cstdio> #include<list> #include<algorithm> #include<cstring> #include<string> #include<queue> #include<stack> #include<map> #include<vector> #include<cmath> #include<memory.h> #include<set> #define ll long long #define eps 1e-7 #define inf 0xfffffff const ll INF = 1ll<<61; using namespace std; //vector<pair<int,int> > G; //typedef pair<int,int > P; //vector<pair<int,int> > ::iterator iter; // //map<ll,int >mp; //map<ll,int >::iterator p; // vector<int> G[35]; int dp[35],vis[35]; int k,n,ans,maxn; void clear() { for(int i=0;i<=k;i++) G[i].clear(); memset(vis,0,sizeof(vis)); memset(dp,0,sizeof(dp)); ans = 0; } int detal(int cur,int pos) { vector<int> &G1=G[cur],&G2=G[pos]; for(int i=0;i<n;i++) if(G1[i] <= G2[i]) return 0; return 1; } int caldp(int cur) { if(vis[cur]) return dp[cur]; int maxnum = 1; vis[cur] = 1; for(int i=1;i<=k;i++) if(i != cur && detal(cur,i)) { int tmp = caldp(i) + 1; maxnum = max(tmp,maxnum); } ans = ans>maxnum?ans:(maxn = cur,maxnum); return dp[cur] = maxnum; } void Printf(int x) { for(int i=1;i<=k;i++) if(dp[i] == dp[x] - 1 && detal(x,i)) { Printf(i); break; } if(x != maxn) printf("%d ",x); else printf("%d",x); } int main() { int x; while(scanf("%d %d",&k,&n)==2) { clear(); for(int i=1;i<=k;i++) { for(int j=0;j<n;j++) { scanf("%d",&x); G[i].push_back(x); } sort(G[i].begin(),G[i].end()); } for(int i=1;i<=k;i++) caldp(i); printf("%d\n",ans); Printf(maxn); puts(""); } return EXIT_SUCCESS; }