目录
1 全排列
2 01背包
3 自然数拆分
4 页码统计
5 汉诺塔
1 全排列
生成从\(1\)到\(n\)的全排列
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int a[25];
bool vis[25];
int n;
int ans=0;
void f(int x){
if(x==n+1){
ans++;
for(int i=1;i<=n;i++){
printf("%5d",a[i]);
}
printf("\n");
return;
}
for(int i=1;i<=n;i++)
{
if(vis[i]==1) continue;
bool q=1;
if(q){
vis[i]=1;
a[x]=i;
f(x+1);
vis[i]=0;
}
}
return ;
}
int main( ){
scanf("%d",&n);
f(1);
printf("%d",ans); //...
return 0;
}
2 01背包问题
设一背包可容纳物品最大质量为\(M\),现有\(n\)件物品,质量是\(m_i(i\in [1,n],i\in N)\),要从这些物品中挑选若干件,使得质量之和恰好是\(K\),询问能否做到.
题解
用\(knap(M,n)\)表示寻找的问题。
(1)先取最后一个物品\(m_n\)放入背包,如果\(m_n=M\),则return true.
(2)若\(m_n<M\),则\(M-m_n<0\),如果还有可选物品。即为\(n>1\),考虑\(knap(M-m_n,n-1)\)是否有解,如果有就return true.否则\(knap(M,n)\)转化为\(knap(M,n-1)\),即放弃最后一个物品,在前\((n-1)\)个物品内考虑问题.
(3)若\(m_n>M\),则第\(n\)件物品不能装入包中,这时如果还有可选物品,即\(n>1\),那么\(knap(M,n)\)转化为\(knap(m,n-1)\)。
bool knap(int m,int n){
if(m[n]==m) return true;
else if(m[n]<m){
if(n>1){
if(knap(m-m[n],n-1)) return true;
else return knap(m,n-1);
}
else return false;
}
else{
if(n>1) return knap(m,n-1);
else return false;
}
}