16.递推

定义:全局规律,每一项均可以由前面的几项计算得出

俩个重要的要素

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<

你可能感兴趣的:(蓝桥杯算法,图论,算法)