http://acm.hdu.edu.cn/showproblem.php?pid=3632
还是做题爽
kill[l][r] 表示通过一定策略 l 是否可以把 l -- r 之间的其他所以人都淘汰掉
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cmath> #define ll long long using namespace std; const int N=105; //const ll MOD = 1000000007; int a[N][N]; int v[N]; int kill[N][N]; int main() { //freopen("data.in","r",stdin); int T; scanf("%d",&T); for(int w=1;w<=T;++w) { int n; scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",&v[i]); memset(kill,0,sizeof(kill)); for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) { scanf("%d",&a[i][j]); if(i==j||(abs(i-j)==1&&a[i][j]==1)) kill[i][j]=1; } for(int k=1;k<=n-2;++k) for(int i=1;i+k+1<=n;++i) { int l=i; int r=i+k+1; for(int m=l+1;m<r;++m) if(kill[l][m]&&kill[m][r]) kill[l][r]=1; for(int m=l;m<r;++m) if(kill[l][m]&&kill[r][m+1]&&a[l][r]) kill[l][r]=1; for(int m=r-1;m>l;--m) if(kill[r][m]&&kill[m][l]) kill[r][l]=1; for(int m=r;m>l;--m) if(kill[r][m]&&kill[l][m-1]&&a[r][l]) kill[r][l]=1; } int k=-1; for(int i=1;i<=n;++i) { if(kill[i][1]&&kill[i][n]&&(k==-1||v[k]<v[i])) k=i; } printf("Case %d: ",w); printf("%d\n",v[k]); } return 0; }