蓝桥杯模拟赛的最后一题
是一个常见的递归
emmm我一直在想它有返回值的情况怎么写,主要是没明白如果都不满足条件,那返回啥呢
不可以不返回,不返回递归就不成立了
都不满足就随便返回一个·
有一个满足就返回满足的那个
都满足就再比较大小
主要要想明白的一点是
递归是全状态搜索惹,到叶节点所有情况的搜索都已经完成了
看你咋选了,要选择更靠近答案的那个值
那么这题有动态规划的做法嘛
我已经写出返回值的的递归了
那么它有重叠子问题吗
搜索到同一个商品包含同样种类的字符并且花费了相同的权值,听起来有点复杂的样子
而且好像没有局部子问题
我觉得应该用不了动规(当然也可能是因为我菜。。)
题目:
我的代码,我只跑了样例,但应该差不离
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
struct node{
int v;
string s;
};
int n;
node aa[1100];
bool check(string s)
{
map<char,int> mm;
for(int i=0;i<s.length();i++)
{
mm[s[i]]++;
if(mm['A']>0&&mm['B']>0&&mm['C']>0)
return true;
}
return false;
}
ll minn=1<<32;
//无返回值递归
void dfs2(int x,node dd)
{
if(x==n) return ;
if(check(dd.s)){
if(dd.v<minn)
minn=dd.v;
return ;
}
dfs2(x+1,dd);
dd.s+=aa[x].s;
dd.v+=aa[x].v;
dfs2(x+1,dd);
}
//只要不满足条件他就会一直往下递归呀,就算到终点回溯了,他的值肯定比某个选了它的值要小!
//自上而下递归到了叶节点,它的状态都已经算好了(搜索完成),之后就看你怎么选了
//如果这里我要用自上而下的,我必然要把字符串当成状态标识符传递下去的
node dfs1(int x,node dd)
{
if(x==n) return dd;
if(check(dd.s)){
return dd;
}
node v1=dfs1(x+1,dd);
dd.s+=aa[x].s;
dd.v+=aa[x].v;
node v2=dfs1(x+1,dd);
if(check(v2.s)&&check(v1.s))
{if(v1.v>v2.v)return v2;
else return v1;}
else{
if(check(v2.s))return v2;
else return v1;
}
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
cin>>aa[i].v>>aa[i].s;
}
node dd;
dd.s="";
dd.v=0;
node t=dfs1(0,dd);
//dfs2(0,dd);
if(check(t.s))
cout<<t.v;
else
cout<<"-1";
}