华为so-胜负猜想 动态规划复习

本文介绍了一种利用递归与动态规划方法解决数字序列博弈问题的技术。该问题中,两个玩家从非递增序列中交替移除数字,目标是使剩余序列变为递增。文章提供了两种解决方案,一是通过递归寻找最长递增子序列,二是采用动态规划高效求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:

输入一个非递增数字序列,甲先取,乙后取。两个人先后取,先达到递增序列则胜。

比如213,甲取1,剩下23则胜。

比如222,甲取2,乙取2,剩下2,则乙取胜

甲胜则输出1,输则输出0;


1、比较直接的方法,从前往后遍历,遇到一个逆序就去解决了,比如213,21出现逆序,解决了他!

一种可能是删了2(删了前面大的),一种是删了1(后面小的)。

接下来递归,终点是序列严格递增。

我们需要最后序列最长的最为判定条件。(其实这就转化为最长子序列的问题了)


和原先序列长度的差值就是需要删的个数,就能判定输赢问题。


先是用递归完成的

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

bool IsUp(string str)
{
	if(str.size()==1)
		return true;
	for(int i=0;i<str.size();++i)
		for(int j=i+1;j<str.size();++j)
			if(str[j]<=str[i])
				return false;
	return true;
}
int maxlen = 0;
void dfs (string str)
{
	if (IsUp(str))
	{
		if(str.size()>maxlen)
		 maxlen = str.size();
		return;
	}
	string temp1;
	string temp2;
	for(int i=1; i<str.size(); ++i)
	{
		if (str[i]<=str[i-1])
		{
			temp1.append(str.begin(),str.begin()+i-1);
			temp1.append(str.begin()+i,str.end());
			temp2.append(str.begin(),str.begin()+i);
			temp2.append(str.begin()+i+1,str.end());
			break;
		}
	}
	//找到递减点,总是删除前面大的或者后面小的
	cout<<"temp1b:"<<temp1<<endl;
	dfs(temp1);
	cout<<"temp1a:"<<temp1<<endl;
	cout<<"temp2b:"<<temp2<<endl;
	dfs(temp2);
	cout<<"temp2a:"<<temp2<<endl;
}
int main()
{
	string str = "3412";
	int slen = str.length();
	dfs(str);
	if((slen-maxlen)%2==1)
		cout<<1<<endl;
	else
		cout<<0<<endl;
	return 0;
}


2、动态规划实现(完成最长子序列问题)

状态转移关系式

d[i]为状态数组

d(i) = max{1, d(j)+1},其中j<i,Str[j]<=Str[i]
#include <iostream>
#include <string>
using namespace std;


int win(string str){
	int *dp = new int[str.size()];
	int len = 0;
	memset(dp,1,str.size()*sizeof(int));
	for (int i=0;i<str.size();++i)
	{
		for(int j=0;j<i;++j)
			if(str[j]<str[i] && dp[j]+1>dp[i])
				dp[i] = dp[j]+1;
		if(dp[i]>len) len = dp[i];
	}
	delete dp;
	return len;
}
int main(){


	string str;
	cin>>str;
	if((str.size()-win(str))%2==1)
		cout<<1;
	else
		cout<<0;
	return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值