一、穷举法框架与特点
1.穷举法定义:
将所有的可能解一一列举出来,然后进行验证,看是否符合整个问题的解的要求,从而得到一个问题的正确的解。
2.穷举法解决问题的一般过程:
构建穷举状态->列出穷举范围->根据条件判断是否合法。
3.穷举优化:
从穷举状态和范围两个方面来考虑
A.预处理无效部分 B.根据实际条件优化,剪枝 C.空间换时间(参考哈希表)
例一:鸡兔同笼
问题分析:··……
代码如下:
#include<bits/stdc++.h>
using namespace std;
int main(){
for(int i=1;i<20;i++){
for(int j=1;j<33;j++){
for(int k=1;k<100;k++){ //优化后可省去此层循环
if((i+j+k==100)&&(5*i+3*j+k/3==100)) cout<<i<<' '<<j<<' '<<k<<endl;
}
}
}
return 0;
}
例二:0-1背包
无实例,代码如下:
#include<bits/stdc++.h>
using namespace std;
int n,wk,w[100010],c[10010],b[10010],j,d[10010];
int main(){
scanf("%d %d",&n,&wk);
for(int i=1;i<=n;i++) scanf("%d",&w[i]);
for(int i=1;i<=n;i++) scanf("%d",&c[i]);
int cmax=0;
memset(b,0,sizeof(b)); b[n]=1;
while(b[0]==0){
int s=0,t=0;
for(int i=1;i<=n;i++){
s+=b[i]*w[i];
t+=b[i]*c[i];
}
if(s<=wk && t>cmax){
cmax=t;
for(int i=1;i<=n;i++) d[i]=b[i];
}
j=n;
while(b[j]==1) j-=1; //过滤1
b[j]+=1;
for(int i=j+1;i<=n;i++) b[i]=0;
}
printf("%d\n",cmax);
for(int i=1;i<=n;i++){if(d[i]==1) cout<<i<<' ';cout<<endl;}
return 0;
}
//穷举优化:预处理无效部分
//根据实际条件优化
//空间换时间(同哈希表)