格斗(区间DP)

这是一篇关于如何应用区间动态规划(区间DP)解决格斗俱乐部比赛问题的文章。比赛有N位选手,形成一个圆圈,每次相邻的两位选手对决,胜利者继续参赛,直到只剩一位冠军。给定选手间的胜负关系矩阵,任务是判断每位选手是否有机会成为冠军。文章指出,不能简单使用图论遍历,而是需要用长度为2N的数组模拟环形结构,并采用区间DP的方法进行求解。
摘要由CSDN通过智能技术生成

题目描述:

格斗俱乐部是格斗爱好者的一个组织,在这里,格斗者们能通过与别的成员进行格斗来释放自己的压力与轻松自己的情绪。最近俱乐部举行了一场比赛,该比赛有N位选手参加,他们将围成一个圆圈,每一场比赛圈内任意的两位相邻的选手均可进行相互的格斗,胜利者将留在圈内进入下轮比赛而失败者则直接被送往医院(没有平局)。比赛是残酷的,最后圈内将只剩下一位选手,他将是总冠军。

  我们做个奇怪的假设,两位选手进行格斗,他们比赛的结果总是确定的。虽然俱乐部的成员们都很喜欢格斗,但是他们仍然很希望能获得总冠军。现在你通过统计已经知道了任意两位选手格斗的结果,你有责任告诉每位选手,如果赛程合适安排的话,他是否可能成为总冠军。

输入:

数据第一行是一个整数N,(1<=N<=40),表示比赛的选手数量。

接下来给出一个N*N的“0”、“1”矩阵A(行内用空格隔开),第i行第j列为 1表示选手i能战胜选手j,否则选手j能战胜选手i。

你可以假定Aij与Aji(i≠j)均是不同的且Aii=0。比赛开始时所有选手按顺时针方向由编号1到编号N站成一个圈,初始时编号1与编号N的选手是相邻的。

输出:

输出包含N行,每行为一个整数“0”或“1”,“1”表示第i号选手有可能成为冠军,“0”表示不可能。

样例输入:样例输出:

3

0 1 1

0 0 1

0 0 0

1

0

0


思路:

在做这道题的时候想到要去环,但没有想到用区间DP的方法去实现(有点菜)。

刚开始想用图论遍历的方法来做,通过1~n个点中的任意一个能否遍历到其他的点,能就输出1,不能就输出0,

但题目中的条件是相邻的两人进行格斗,所以这个想法就无疾而终。

用长度2倍的数组去环,再进行区间DP。

推荐一个博客

代码:

#include<bits/stdc++.h>
using  namespace  std;
const int maxn=55;
int n;
int a[maxn*2][maxn*2];//两倍的数组(解决环) 
int f[maxn*2][maxn*2];//f[i][j]表示第i个人或第j个人能把i+1~j-1的人打败 
void init()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	  for(int j=1;j<=n;j++)
	    {
	      scanf("%d",&a[i][j]);
	      a[i][j+n]=a[i][j];//将环转换成长度为2倍的数组,并转移输赢关系 
	      a[i+n][j]=a[i][j];
	      a[i+n][j+n]=a[i][j];
	    }
}
void work()
{
	for(int i=1;i<=2*n;i++)
	  f[i][i+1]=true;//初值 
	for(int i=2*n-2;i>=1;i--)
	  for(int j=i+2;j<=2*n;j++)//保证i<j 
	    for(int k=i+1;k<=j-1;k++)
	      if((i<k) &&(k<j) &&(a[i][k]==1 ||a[j][k]==1) &&(f[i][k]==true) &&(f[k][j]==true))
	        //k是中间点,位于i和j之间,两端的i和j能打败k,i或k能打败i和k之间的人,j或k能打败j和k之间的人,
			//那么i或j就能打败i和j之间的人 
	        f[i][j]=true;
}
int  main()
{
  init();
  work();
  for(int i=1;i<=n;i++)
    {
      if(f[i][i+n]==true) cout<<'1'<<endl;//n个人都被打败 
      else                cout<<'0'<<endl;
    }
  return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值