一个笔试题,射击靶子最高得分问题

16 篇文章 0 订阅

 有一排靶子,靶子上有不同的得分,亦枪手射击靶子,集中某个靶子则得到相应的得分,但是没集中一个靶子都会破坏掉它两侧的两个靶子(如果有的话),求这个枪手能够得到的最高分:

输入 : 第一行 整数n,

            第二行 n 个整数表示 每个八字的分数(分数最少为1)

输出   该枪手的最高得分:


解题思想: 枪手第一枪有n个选择,第二枪的选择是第一枪打完后剩下的靶子数量,第三枪的选择是前两抢打完后剩下的靶子数量,以此类推,直到所有的靶子被射击完。

整个过程构成了一棵空间树,依次遍历到空间树的每个叶子节点,找出最优解

#include <iostream>
#include <vector>
using namespace std;
/*
* 解体思路: 采用回溯法构造解空间树,搜索最优解
* 每一层可以射击的靶子是当前所有没有被射击的靶子
* 则搜索该层射击每个靶子后的子树,当所有靶子都被
* 射击的时候,则搜索结束,如果当前得分高于最高分
* 更新最高分*/
//vec 代表 每个位置靶子得分
//flag true 代表该位置被射击,false 代表未射击
//cur 是当前得分
//max 是最高得分
void findBest(vector<int> &vec,vector<bool> &flag,int cur,int &max){
		int pos = -1;
		vector<bool> shoot(vec.size());
		while(pos < (int)vec.size()){
			while(flag[++pos]);// 一次射击这一枪可以射击的所有靶子
			//cout<<"shoot :"<<pos<<endl; 
			if(pos < vec.size()){//射击 pos 位置的靶子
				flag[pos] = true;
				shoot[pos]=true;
				cur += vec[pos];
				if(pos-1 >= 0 && !flag[pos-1]){
					flag[pos-1] = true;
					shoot[pos-1]=true;
				} 
				if(pos+1 < vec.size() && !flag[pos+1]){
					flag[pos+1]=true;
					shoot[pos+1] = true;
				} 
				findBest(vec,flag,cur,max);//搜索下层子树
				//恢复射击pos 位置子树之前的状态
				cur -= vec[pos];
				for(int m= 0; m < shoot.size(); ++m){
					if(shoot[m]){
						flag[m] = false;
						shoot[m] = false;
					}
				}
				//跳出之后将会选择该层未被射击的下一个靶子射击
			}
			else if( cur > max)// 所有靶子都被射击,更新最高分
					max =cur;
		}
}
int main(){
	int n = 0,max = 0;
	cin>>n;
	vector<int> vec(n);
	for(int i = 0; i < n; ++i)
		cin>>vec[i];
	//vector<int> vec = {4,6,3};
	vector<bool> flag(vec.size());
	findBest(vec,flag,0,max);
	cout<<endl<<max<<endl;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值