测试数据链接
暴力搜索可以30,对于每种情况,去枚举每个挑战者就行了
正解DP :O(N^3)
DP[i][j]为i,j是否可以相邻,也就是中间的人全部PK掉了,如果DP[i][i+n]为真,就说明i是可以胜出的!
枚举起点i,终点j,中间点k
如果DP[i][k]&&DP[k][j]为真,也就是说i,j中间只有k了
那么判断i,j可以相邻的情况有两个
一个是i挑战k成功了,另一个是k挑战j失败了
只要上面的两种情况一个成立,那么DP[i][j]为真
#include <cstdio>
#include <iostream>
#define ll long long
using namespace std;
bool map[201][201];
bool dp[302][302];
int tes[302];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
scanf("%d",&map[i][j]);
}
for(int i=1;i<=2*n-1;i++)
dp[i][i+1]=1;
for(int i=1;i<=n;i++)
tes[i]=tes[i+n]=i;//找原位置
for(int i=2*n;i>=1;i--)
for(int j=i+1;j<=2*n;j++)
for(int k=i;k<=j;k++)
{
if(dp[i][k]&&dp[k][j])
if((map[tes[i]][tes[k]]==1)||(map[tes[k]][tes[j]]==0)) dp[i][j]=1;
}
for(int i=1;i<=n;i++)
if(dp[i][i+n]) printf("%d ",i);
return 0;
}