前言
最近做递归搜索相关的题目感觉刷出手感了,哈哈。
先放题目链接:P2036 [COCI2008-2009#2] PERKET
解题思路:
基础的递归搜索策略。在这里,我选择利用search函数来递归,其具体的含义是,在ingred[]数组的left到right区间上,当前已经选择好的配料的总酸度为total_s,总苦度为total_b时的最小差值。初始即为从0到n-1上搜索,初始的总酸度为1,初始的总苦度为0。每次进入递归以后,先判断是否越界,即left是否已经大于了right。是的话则表示无法比较,则返回infinity(即无限大);然后计算已经选择了的配料总酸度和总苦度的差值,得到一个min,然后在left+1和right区间上,递归查找选择ingred[left]和不选择ingred[left]对应的最小总酸度和总苦度差值。三者的最小值即为要求的最低差值。
#include <stdio.h>
#include <stdlib.h>
#define inf 1400000000
struct node{
int s;
int b;
};
struct node ingred[20];
int search(struct node ing[],int left,int right,int total_s,int total_b){ //search的含义是对于数组ingred[]在left到right区间内取配方的最小值
if(left>right)
return inf;
int min,min1,min2,i;
if(total_s==1&&total_b==0){
min=inf;
}else{
min=abs(total_s-total_b);
} //当前min
min1=search(ing,left+1,right,total_s*ing[left].s,total_b+ing[left].b); //取当前node[left]后在left+1到right上搜索min
min2=search(ing,left+1,right,total_s,total_b); //不取当前node[left]后在left+1到right上搜索min
if(min<=min1&&min<=min2){
return min;
}else if(min1<=min&&min1<=min2){
return min1;
}else if(min2<=min&&min2<=min1){
return min2;
}
}
int main(int argc, char *argv[]) {
int n,i,total_s=1,total_b=0,minus_min=inf,min;
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%d%d",&ingred[i].s,&ingred[i].b);
}
min=search(ingred,0,n,total_s,total_b);
printf("%d",min);
return 0;
}