0、剪枝的方法
1、小猫爬山
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 20;
int n, m;
int w[N];
int sum[N];
int ans = N;
void dfs(int u, int k)
{
// 最优性剪枝
if (k >= ans) return;
if (u == n)
{
ans = k;
return;
}
for (int i = 0; i < k; i ++ )
if (sum[i] + w[u] <= m) // 可行性剪枝
{
sum[i] += w[u];
dfs(u + 1, k);
sum[i] -= w[u]; // 恢复现场
}
// 新开一辆车
sum[k] = w[u];
dfs(u + 1, k + 1);
sum[k] = 0; // 恢复现场
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i ++ ) cin >> w[i];
// 优化搜索顺序
sort(w, w + n);
reverse(w, w + n);
dfs(0, 0);
cout << ans << endl;
return 0;
}
2、数独
/*
81个字符的字符串->在计算中变向转换成9*9的矩阵。
将变向的9*9矩阵转换到,每一行、列和九宫格的9位的01串(int) draw实现
9位的01串从右向左依次表示123456789是否存在。0表示存在,1表示不存在可填。
预处理 0~1<<8 01串中1的个数。
log2(0) log2(1) log2(8) 中的n 目的是当某个01串,首位是1,其他位是0.得到1的位置。
init->将行、列、九宫格的01串全部置成1。
draw:最初将变向的9*9矩阵转换到,每一行、列和九宫格的9位的01串。
在dfs中设置01串中1的位置为0,以及将0的位置变成1。
lowbit:返回一个01串中,最后一个1,以及它后边的0.
*/
/*
预处理 one map为二进制优化做准备
初始化 将所有行、列、九宫格的01串全部变成1.
draw 将字符串中还有数字的地方修改到01串中。计算空格数。
dfs以空格为0试截止。先找到所有空格中分支最少的空格。
对分支最少的空格优先dfs。
*/
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 9, M = 1 << N;
//one快速求出一个状态有多少个1
//map求出1og2(n)中的n
int ones[M], map[M];
int row[N