回溯法 可以用来对问题的空间解进行搜索 回溯法将问题的所有可能解构成树 然后用dfs 进行搜索 遍历每种解的情况 找到符合要求的解
回溯法的基本格式 :
void dsf(参数)
{
if(边界,结束条件)
{
操作;
return ;
}
if(条件)
{
回溯前操作;
dfs(参数);
回溯后还原;
}
}
下面给出两个例子:
0-1背包问题 :
给定一个容积为c的背包,去尝试装n个重量为wi、价值为vi的物体,求能装下的物体的最大价值。 例如,当
n=3,c=30,W[]={16,15,15},v={45,25,25}时,可以装下的是后两个物体,最大价值为50。
代码如下:
#include<stdio.h>
int weight[]={16,15,15};
int value[]={45,25,25};
int tempvalue=0,tempweight=0;
int maxvalue=0;
int c=30;
void dfs(int t){
if (t==3)//结束条件
{
if (tempvalue>maxvalue&&tempweight<=c) //操作
maxvalue=tempvalue;
return ;
}
dfs(t+1);//搜索
if (tempweight<=c)
{
tempweight+=weight[t];
tempvalue+=value[t];//回溯前操作
dfs(t+1);//搜索
tempweight-=weight[t];
tempvalue-=value[t];//回溯后还原
}
}
int main (){
dfs(0);
printf ("%d\n",maxvalue);
return 0;
}
李白打酒问题:
话说大诗人李白,一生好饮。幸好他从不开车。
一天,他提着酒壶,从家里出来,酒壶中有酒2斗。他边走边唱:
无事街上走,提壶去打酒。
逢店加一倍,遇花喝一斗。
这一路上,他一共遇到店5次,遇到花10次,已知最后一次遇到的是花,他正好把酒喝光了。
请你计算李白遇到店和花的次序,可以把遇店记为a,遇花记为b。则:babaabbabbabbbb 就是合理的次序。像这样的
答案一共有多少呢?请你计算出所有可能方案的个数(包含题目给出的)。
代码如下:
#include <stdio.h>
int wind=2;
int flower=0,shop=0;
int count=0;
void dfs(int t){
if (flower==9&&shop==5&&wind==1)//结束条件
{
count++;
}
if (flower<9)//条件
{
flower++;
wind--;//回溯前操作
dfs(t+1);
flower--;
wind++; //回溯后还原
}
if (shop<5)//条件
{
shop++;
wind*=2; //回溯前操作
dfs(t+1);
shop--;
wind/=2;//回溯后还原
}
}
int main (){
dfs(0);
printf("%d\n",count);
return 0;
}