小白书上讲的很清楚,因为没有起点和终点,所以这题用记忆化搜索。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<vector>
#define LL long long
using namespace std;
const int maxn=1e4+10;
const double eps=1e-6;
int k,n;
int a[40][20];
int b[40][40];
int dp[40];
int ddp(int i)
{
int &ans=dp[i];
if(ans)
return ans;
ans=1;
for(int j=0;j<k;j++)
{
if(b[i][j])
ans=max(ans,ddp(j)+1);
}
return ans;
}
void init(int k,int n)
{
memset(b,0,sizeof(b));
for(int i=0;i<k;i++)
{
for(int j=0;j<k;j++)
{
int flag=1;
for(int t=0;t<n;t++)
{
if(a[i][t]<=a[j][t])
{
flag=0;
break;
}
}
if(flag)
b[i][j]=1;
}
}
}
void print(int i)
{
for(int j=0;j<k;j++)
if(b[i][j]&&dp[i]==dp[j]+1)
{
print(j);
break;
}
cout<<i+1<<' ';
}
int main()
{
while(cin>>k>>n)
{
for(int i=0;i<k;i++)
{
for(int j=0;j<n;j++)
scanf("%d",&a[i][j]);
sort(a[i],a[i]+n);
}
init(k,n);
cout<<endl;
memset(dp,0,sizeof(dp));
for(int i=0;i<k;i++)
dp[i]=ddp(i);
int ans=0;
int t;
for(int i=0;i<k;i++)
{
if(dp[i]>ans)
{
t=i;
ans=dp[i];
}
}
if(ans)
{
cout<<ans<<endl;
print(t);
cout<<endl;
}
else
cout<<0<<endl;
}
return 0;
}