https://www.luogu.com.cn/problem/P1157(dfs)
#include<bits/stdc++.h> //万能头 using namespace std; int m,n,s[100]; //s[]用来标记数 bool vis[100]; //vis[]表示一个数是否可以使用,1表示可以使用,0表示不能使用 void dfs(int k) //dfs深搜 { if(k==n+1) //前n个位置都填过了 { for(int j=1;j<=n;j++) cout<<setw(3)<<s[j]; //将填入的数依次输出 cout<<endl; //换行 return ; //结束本次调用 } for(int i=s[k-1];i<=m;i++) //将每个数遍历一遍,注意,后一个数要大于前一个数,所以i要从s[k-1]开始遍历 { if(vis[i]) //如果i这个数还没有使用 { //就使用它 s[k]=i; //将i这个数填入s数组中 vis[i]=0; //标记i这个数已经使用过了 dfs(k+1); //调用下一层 vis[i]=1; //回溯,标记i这个数还未使用 } } } int main() { s[0]=1; //初始化,不然dfs(1)时,for循环无法工作 memset(vis,1,sizeof(vis)); //将vis数组全部标为可以使用 cin>>m>>n; //输入 dfs(1); //从第一个数开始搜索 }https://www.luogu.com.cn/problem/P1157(dfs)
#include<iostream> #include<iomanip> #include<algorithm> int x[30];//x[i]代表第i选或不选,0代表选,1代表不选 using namespace std; int main() { int n, r; //scanf("%d%d", &n, &r);//读入n、r cin >> n >> r; for (int i = r + 1; i <= n; ++i) x[i] = 1; //赋初始值 do { for (int i = 1; i <= n; ++i) if (x[i] == 0)// printf("%3d", i);//如果是0就输出,注意三个常宽 cout << setw(3) << i; //printf("\n");//换行 cout << endl; } while (next_permutation(x + 1, x + n + 1));//生成下一个 return 0;//返回 }next_permutation(x + 1, x + n + 1)详解: https://blog.csdn.net/howardemily/article/details/68064377
https://www.luogu.com.cn/problem/P3392
#include<iostream> #include<algorithm> using namespace std; int n, m, ans , w[51], b[51], r[51]; string s; inline int check(char c) { int tot = 0; for (int i = 0; i < m; ++i) if (s[i] != c)++tot; return tot; } int main() { cin >> n >> m; ans = n * m; for (int i = 1; i <= n; ++i) { cin >> s; w[i] = w[i - 1] + check('W'); b[i] = b[i - 1] + check('B'); r[i] = r[i - 1] + check('R'); } for (int i = 1; i < n - 1; ++i) for (int j = i + 1; j < n; ++j) ans = min(ans, w[i] + b[j] - b[i] + r[n] - r[j]); cout << ans; return 0; }解析:开数组w[i],b[i],r[i],分别表示把前ii行涂成白、蓝、红需要涂的格子数
设第11行到第ii行是白色
第i+1i+1行到第jj行是蓝色
则第j+1j+1行到第nn行是红色
此时代价为wi+bj-bi+rn-rj 枚举i,j取最小值即可