定义:全局规律,每一项均可以由前面的几项计算得出
俩个重要的要素
1.边界:递推的起始点
2.递推关系式:当前项与前面几项的关系
习题:
1188:菲波那契数列(2)
#include
using namespace std;
const int N=1e6+10;
const int M=1e3;
int a[N];
int main(){
int n;cin>>n;
while(n--){
int x;cin>>x;
//边界
a[1]=1;a[2]=1;
for(int i=3;i<=x;i++){
//递推关系式
a[i]=(a[i-1]%M+a[i-2]%M)%M;
}
cout<
1190:上台阶
#include
using namespace std;
const int N=72;
long long a[N];
int main(){
//边界
a[0]=1;a[1]=1;a[2]=2;
for(int i=3;i<=71;i++){
//递推关系式
a[i]=a[i-1]+a[i-2]+a[i-3];
}
while(1){
int x;cin>>x;
if(!x) break;
cout<
1312:【例3.4】昆虫繁殖
#include
using namespace std;
#define int long long
const int M=51;
int mom[M],baby[M];
signed main(){
int x,y,z;cin>>x>>y>>z;
//1 2 8
for(int i=1;i<=x;i++){
//边界
mom[i]=1;
baby[i]=0;
}
for(int i=x+1;i<=z+1;i++){
//递推关系式
baby[i]=mom[i-x]*y;
mom[i]=mom[i-1]+baby[i-2];
}
cout<
signed
//signed int == int ==signed-->都是有符号整形-->(-2^31,+2^31-1)
//unsigned int-->无符号整形-->(0,2^32)
十年OI一场空,不开long long 见祖宗
#define int long long
signed main(){
return 0;
}
数位递推
1313:【例3.5】位数问题
#include
using namespace std;
#define int long long
const int N=1e3+10;
const int m=12345;
int odd[N],even[N];
signed main(){
//数位递推:
int n;cin>>n;
//边界:
odd[1]=1;even[1]=9;
for(int i=2;i<=n;i++){
if(i!=n){
//如果不是首位
//要得到奇数个3 要么 奇加偶 要么 偶加奇
odd[i]=(even[i-1]*1%m+odd[i-1]*9%m)%m;
//要得到偶数个3 要么 偶加偶 要么 奇加奇
even[i]=(even[i-1]*9%m+odd[i-1]*1%m)%m;
}
else{
//如果是首位
//要得到奇数个3 要么 奇加偶 要么 偶加奇
odd[i]=(even[i-1]*1%m+odd[i-1]*8%m)%m;
//要得到偶数个3 要么 偶加偶 要么 奇加奇
even[i]=(even[i-1]*8%m+odd[i-1]*1%m)%m;
}
}
cout<
二维递推
1314:【例3.6】过河卒(Noip2002)
#include
using namespace std;
#define int long long
const int N=1e2+10;
int f[N][N];//递推数组 用来表示从远点到i j 点可到达的方案数
bool vis[N][N];//标记码的控制点
int n,m,cx,cy;
int dx[]={1,1,-1,-1,2,2,-2,-2};
int dy[]={2,-2,2,-2,1,-1,1,-1};
signed main(){
cin>>n>>m>>cx>>cy;
//标记马的控制点
vis[cx][cy]=1;
//s
for(int i=0;i<8;i++){
int bx=cx+dx[i],by=cy+dy[i];
if(bx<0||bx>n||by<0||by>m) continue;
vis[bx][by]=1;
}
//边界:
f[0][0]=1;
//处理第0行
for(int j=1;j<=m;j++){
f[0][j]=f[0][j-1];
if(vis[0][j]) f[0][j]=0;
}
//处理第0列
for(int i=1;i<=n;i++){
f[i][0]=f[i-1][0];
if(vis[i][0]) f[i][0]=0;
}
//递推
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
f[i][j]=f[i-1][j]+f[i][j-1];
if(vis[i][j]) f[i][j]=0;
}
}
cout<
吃糖果
#include
using namespace std;
#define int long long
const int N=1e2+10;
int a[N];
signed main(){
int n;cin>>n;
a[1]=1;a[2]=2;
for(int i=3;i<=N-1;i++){
a[i]=a[i-1]+a[i-2];
}
cout<
1194:移动路线
#include
using namespace std;
const int N=1e2+10;
int f[N][N];
int main(){
int n,m;cin>>n>>m;
//边界
for(int j=1;j<=n;j++){
f[1][j]=1;
}
for(int i=1;i<=m;i++){
f[i][1]=1;
}
//递推关系式
for(int i=2;i<=m;i++){
for(int j=2;j<=n;j++){
f[i][j]=f[i-1][j]+f[i][j-1];
}
}
cout<
1191:流感传染
#include
#include
using namespace std;
#define int long long
const int N=1e2+10;
int a[N][N];
bool vis[N][N];
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
signed main(){
int n,cnt=0;cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
//对输入数据进行特殊化处理
char c;cin>>c;
//1表示没病,0表示没人,-1表示有病
if(c=='.') a[i][j]=1;
else if(c=='@') a[i][j]=-1,cnt++;//发现有病 cnt++
}
}
int m;cin>>m;
for(int day=2;day<=m;day++){
//参数1是数组名,参数2是置0,参三是数组大小
//新的一天,标记数组清零
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(a[i][j]==-1&&!vis[i][j]){//要是有病
for(int k=0;k<4;k++){
int cx=i+dx[k];int cy=j+dy[k];
if(cx<1||cx>n||cy<1||cy>n||a[cx][cy]==0||a[cx][cy]==-1) continue;
if(a[cx][cy]==1) a[cx][cy]=-1,vis[cx][cy]=true,cnt++;
}
}
}
}
}
cout<
放苹果***(没懂)
#include
using namespace std;
#define int long long
const int N=1e2+10,M=1e2+10;
int f[M][N];
signed main(){
int t,m,n;
for(int i=0;i<=10;i++){
for(int j=0;j<=10;j++){
if(i<=1||j<=1) f[i][j]=1;
else if(i>t;
while(t--){
cin>>m>>n;
cout<
踩方格
#include
using namespace std;
#define int long long
const int N=1e2+10;
int f[N];
signed main(){
int n;cin>>n;
//边界
f[1]=3;f[2]=7;
for(int i=3;i<=n;i++){
f[i]=f[i-1]*2+f[i-2];
}
cout<