# 算法_回溯(最佳调度问题、八皇后问题、0-1背包、整数拆分、666、工作分配问题)

## 最佳调度问题

7 3
2 14 4 16 6 5 3


17


#include <iostream>
using namespace std;
int n,k,a[20],b[20],Min = 1000000000;
void s(int x)
{
if (x == n)
{
int Max = b[0];
for (int i = 1;i <= k;i++)
if (b[i] > Max)
Max = b[i];
if (Max < Min)
Min = Max;
return;
}
for (int i = 0;i < k;i++)
{
if (b[i] + a[x] > Min)
continue;
b[i] += a[x];
s(x+1);
b[i] -= a[x];
}
}
int main()
{
int i;
cin>>n>>k;
for (i = 0; i < n;i++)
cin>>a[i];
for (i = 0;i < k;i++)
b[i] = 0;
s(0);
cout<<Min<<endl;
return 0;
}


## 八皇后问题

3


None


6


. Q . . . .
. . . Q . .
. . . . . Q
Q . . . . .
. . Q . . .
. . . . Q .

. . Q . . .
. . . . . Q
. Q . . . .
. . . . Q .
Q . . . . .
. . . Q . .

. . . Q . .
Q . . . . .
. . . . Q .
. Q . . . .
. . . . . Q
. . Q . . .

. . . . Q .
. . Q . . .
Q . . . . .
. . . . . Q
. . . Q . .
. Q . . . .


#include <iostream>
using namespace std;
int N, flag = 0;
int f(int x,int y,char a[][1000]){
int x1,i,y1=y,m;
for (i = y-1; i >= 0; i--){
x1 = 0, y1 = i ;
m = y - y1;
while (a[y1][x1] != 'Q')
x1++;
if (x1 == x)
return 0;
if (x1 - m == x || x1 + m == x)
return 0;
}
return 1;
}
int s(int x, char a[][1000])
{
int i, j;
if (x == N)
{
if(flag)
cout << endl;
flag = 1;
for (i = 0; i<x; i++){
for (j = 0; j < N; j++){
if (a[i][j] == 'Q')
cout << a[i][j];
else
cout << ".";
if(j!=N-1)
cout<<' ';
}
cout << endl;
}
return 0;
}
for (j = 0; j < N; j++)
if (f(j,x , a)){
a[x][j] = 'Q';
s(x+1, a);
a[x][j] = '.';
}
return 1;
}
int main()
{
char a[1000][1000];
cin >> N;
s(0, a);
if (flag == 0)
cout << "None"<<endl ;
return 0;
}


## 0-1背包

5 10
2 6
2 3
6 5
5 4
4 6


15


#include <iostream>
using namespace std;
int dp[105][1005] = { 0 };
int n, c;
int w[105], v[105];
void solve(){
for (int i = 0; i<n; i++){
for (int j = 0; j <= c; j++){
if (j<w[i]){
dp[i + 1][j] = dp[i][j];
}
else{
if (dp[i][j - w[i]] + v[i]>dp[i][j])
dp[i + 1][j] = dp[i][j - w[i]] + v[i];
else
dp[i + 1][j] = dp[i][j];
}
}
}
}

int main(){
cin >> n >> c;
for (int i = 0; i<n; i++){
cin >> w[i] >> v[i];
}
solve();
cout << dp[n][c] << endl;
return 0;
}



## 整数拆分

4


4 = 1 + 1 + 1 + 1
4 = 1 + 1 + 2
4 = 1 + 3
4 = 2 + 2
4


#include <iostream>
#include <vector>
using namespace std;
int n, num;
vector<int> v;

void dfs(int k, int sum) {
if (sum > n) return;
if (sum == n) {
cout << n << " = ";
for (int i = 0; i < v.size(); i++) {
if (i) cout << " + ";
cout << v[i];
}
cout << endl;
num++;
return;
}
for (int i = k; i < n; i++) {
v.push_back(i);
dfs(i, sum + i);
v.pop_back();
}
}

int main() {
cin >> n;
dfs(1, 0);
cout << num<<endl;
return 0;
}


## 666

3 3
6 6 7
3 8 3
7 9 5


2 1 2
0 3 0
1 1 0
10


#include <iostream>
#include <vector>
using namespace std;
int n, m, b[10000][10000] ,a[10000][10000];
int s(int x, int y, int w, int fn){
int z = 0, z1 = 0;
if (a[x][y + 1] >= 6 && fn != 3){
if (w == 2)
z1++;
else
z += s(x, y + 1, w + 1, 1);
}
if (a[x + 1][y] >= 6 && fn != 4){
if (w == 2)
z1++;
else
z += s(x + 1, y, w + 1, 2);
}
if (a[x][y - 1] >= 6 && fn != 1){
if (w == 2)
z1++;
else
z += s(x, y - 1, w + 1, 3);
}
if (a[x - 1][y] >= 6 && fn != 2){
if (w == 2)
z1++;
else
z += s(x - 1, y, w + 1, 4);
}
if (w == 2)
return z1;
else
return z;
}
int main() {
int sum=0;
cin >> m >> n;
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++)
cin >> a[i][j];
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++){
if (a[i][j] >= 6)
b[i][j] = s(i, j, 1, 0);
else
b[i][j] = 0;
}
for (int i = 1; i <= m; i++){
for (int j = 1; j <= n; j++){
if (j != 1)cout << " ";
cout << b[i][j];
sum += b[i][j];
}
cout << endl;
}
cout << sum<<endl;
return 0;
}


## 工作分配问题

3
10 2 3
2 3 4
3 4 5


9


#include <iostream>
#include <algorithm>
using namespace std;
int n, cost = 0;
int c[100][100];
void work(int i, int countt)
{
if (i > n && countt < cost)
{
cost = countt;
return;
}
if (countt< cost)
{
for (int j = 1; j <= n; j++)
{
if (c[0][j] == 0)
{
c[0][j] = 1;
work(i + 1, countt + c[i][j]);
c[0][j] = 0;
}
}
}
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
cin >> c[i][j];
c[0][j] = 0;
}
cost += c[i][i];
}
work(1, 0);
cout << cost << endl;
return 0;
}


11-03 1578

09-26 2952
04-06 1万+
12-30 9136
05-17 656
01-12 2845
10-27 1684
07-23 1354
12-29 1822
05-01 686
06-07 508
07-20 1010
05-07 817