这个题是个DAG问题,求最长的可以前面盒子放后面盒子里的个数
直接记忆化搜索即可
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=101;
int ans,pos,n,m,a[maxn][maxn],is[maxn][maxn],dp[maxn];
int DP(int index)
{
if(dp[index])
return dp[index];
dp[index]=1;
for(int i=0;i<n;i++)
if(i!=index&&is[i][index])
dp[index]=max(dp[index],DP(i)+1);
return dp[index];
}
bool Is(int i,int j)
{
for(int k=0;k<m;k++)
if(a[i][k]>=a[j][k])
return false;
return true;
}
void Print(int index)
{
for(int i=0;i<n;i++)
if(dp[i]==dp[index]-1&&is[i][index])
{
Print(i);
break;
}
if(index==pos)
printf("%d",index+1);
else
printf("%d ",index+1);
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(dp,0,sizeof(dp));
memset(is,0,sizeof(is));
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
scanf("%d",&a[i][j]);
sort(a[i],a[i]+m);
}
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(i==j)
continue;
is[i][j]=Is(i,j);
}
ans=0;
for(int i=0;i<n;i++)
{
int ita=DP(i);
if(ans<ita)
{
ans=ita;
pos=i;
}
}
printf("%d\n",ans);
Print(pos);
printf("\n");
}
return 0;
}