【洛谷_P2016】战略游戏

针对战略游戏中古城堡的士兵部署问题,采用树形动态规划算法,通过计算最小士兵数量覆盖所有道路,提供了一种有效解决方案。

战略游戏


Description

Bob喜欢玩电脑游戏,特别是战略游戏。但是他经常无法找到快速玩过游戏的办法。现在他有个问题。他要建立一个古城堡,城堡中的路形成一棵树。他要在这棵树的结点上放置最少数目的士兵,使得这些士兵能了望到所有的路。注意,某个士兵在一个结点上时,与该结点相连的所有边将都可以被了望到。
  请你编一程序,给定一树,帮Bob计算出他需要放置最少的士兵。

Input

输入文件中数据表示一棵树,描述如下:
  第一行 N,表示树中结点的数目。
  第二行至第N+1行,每行描述每个结点信息,依次为:该结点标号i,k(后面有k条边与结点I相连),接下来k个数,分别是每条边的另一个结点标号r1,r2,…,rk。
  对于一个n(0 < n <= 1500)个结点的树,结点标号在0到n-1之间,在输入文件中每条边只出现一次。

Output

输出文件仅包含一个数,为所求的最少的士兵数目。
例如,对于如右图所示的树:
答案为1(只要一个士兵在结点1上)。

Sample Input

样例1

4
0 1 1
1 2 2 3
2 0
3 0

样例1图在这里插入图片描述

样例2

5
3 3 1 4 2
1 1 0
2 0
0 0
4 0

Sample Output

样例1

1

样例2

2

解题思路

挺简单的一道树形DP,我们用F[i][1]表示当前点放人的情况,用F[i][0]表示当前点不放人的情况,动态转移方程如下:
f[now][0]+=f[a[now][i]][1];f[now][0]+=f[a[now][i]][1];f[now][0]+=f[a[now][i]][1];
f[now][1]+=min(f[a[now][i]][1],f[a[now][i]][0]);f[now][1]+=min(f[a[now][i]][1],f[a[now][i]][0]);f[now][1]+=min(f[a[now][i]][1],f[a[now][i]][0]);
程序如下:

#include<iostream>
#include<cstdio>
using namespace std;

int n,a[1510][1510],hd[151000];
int b[151000],f[151000][2];

void dp(int now)
{
	b[now]=1;
	f[now][1]=1;
	for(int i=1;i<=hd[now];i++)
	{
		if(b[a[now][i]])
			continue; 
		dp(a[now][i]);
		f[now][0]+=f[a[now][i]][1];
		f[now][1]+=min(f[a[now][i]][1],f[a[now][i]][0]);
	}
}

int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		int x,k;
		scanf("%d%d",&x,&k);
		for(int j=1;j<=k;j++)
		{
			int t;
			scanf("%d",&t);
			a[x][++hd[x]]=t;
			a[t][++hd[t]]=x;
		}
	}
	dp(0);
	cout<<min(f[0][1],f[0][0])<<endl;
}

洛谷P5647是“[NOI2019] 斗主地”这道题。 ### 题目内容 这道题模拟了一个斗地主的游戏场景,给定手牌和出牌规则等信息,要求按照规则完成一系列的操作并给出结果。其具体的规则和输入输出要求较为复杂,详细的题目描述可以在洛谷官网该题页面查看。 ### 解题思路 - **数据处理**:需要对输入的手牌、出牌等信息进行有效的存储和处理,可能会使用数组或其他数据结构来表示手牌和牌型。 - **牌型判断**:实现各种牌型的判断函数,例如单张、对子、顺子等。这需要对每种牌型的规则有清晰的理解,并编写相应的逻辑来判断当前手牌是否符合某种牌型。 - **出牌策略**:根据游戏规则和当前局面,制定合理的出牌策略。这可能涉及到贪心算法、动态规划等思想,以找到最优的出牌方式。 - **模拟游戏过程**:按照游戏规则模拟整个出牌过程,处理各种情况,如出牌、跟牌、判断胜负等。 ### 代码示例(Python) ```python # 以下是一个简化的示例代码框架,实际完整代码需要根据具体规则详细实现 # 定义牌型判断函数 def is_single(cards): return len(cards) == 1 def is_pair(cards): return len(cards) == 2 and cards[0] == cards[1] # 模拟出牌过程 def play_game(): # 初始化手牌等信息 hand_cards = [1, 2, 3, 4, 5] # 示例手牌 while hand_cards: # 这里需要实现具体的出牌策略 if is_single(hand_cards): # 出单张 played_card = hand_cards.pop(0) print(f"出单张: {played_card}") elif is_pair(hand_cards[:2]): # 出对子 played_cards = hand_cards[:2] hand_cards = hand_cards[2:] print(f"出对子: {played_cards}") else: # 其他情况,可根据实际规则处理 pass print("手牌出完,游戏结束") # 调用函数开始游戏 play_game() ```
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值