3.29~4.5递归

版权声明: https://blog.csdn.net/zjh_2017/article/details/79829453

T1拍卖

此题很基本,递归式只要考虑两种情况,是-a还是-b。

#include<bits/stdc++.h>
using namespace std;
long long w,p,a,b,f[1000010];
inline int read()
{
    int num=0,flag=1;
    char c=getchar();
    for (;c<'0'||c>'9';c=getchar())
    if (c=='-') flag=-1;
    for (;c>='0'&&c<='9';c=getchar())
    num=(num<<3)+(num<<1)+c-48;
    return num*flag;
}
long long dfs(long long k)
{
    if (f[k]>=0) return f[k];//记忆化搜索
    if (k<p) return 0;//越界
    if (k==p) return 1;//边界
    return f[k]=dfs(k-a)+dfs(k-b);
}
int main()
{
    w=read();
    p=read();
    a=read();
    b=read();
    memset(f,-1,sizeof(f));
    f[p]=1;
    printf("%lld\n",dfs(w));
    return 0;
}

T2传球游戏

此题也比较基本,递归式也只考虑两种情况,是传给左边的人还是右边的人。但是要加两个特判,因为它是一个环。

#include<bits/stdc++.h>
using namespace std;
long long n,m,f[50][50];
inline int read()
{
    int num=0,flag=1;
    char c=getchar();
    for (;c<'0'||c>'9';c=getchar())
    if (c=='-') flag=-1;
    for (;c>='0'&&c<='9';c=getchar())
    num=(num<<3)+(num<<1)+c-48;
    return num*flag;
}
long long dfs(long long k,long long t)
{
    if (f[k][t]>=0) return f[k][t];//记忆化搜索
    if (t==0)
    {
        if (k==1) return 1;//边界
        return 0;
    }
    if (k==1) return f[k][t]=dfs(2,t-1)+dfs(n,t-1);//特判
    if (k==n) return f[k][t]=dfs(1,t-1)+dfs(n-1,t-1);//特判
    return f[k][t]=dfs(k-1,t-1)+dfs(k+1,t-1);
}
int main()
{
    n=read();
    m=read();
    memset(f,-1,sizeof(f));
    f[1][0]=1;
    printf("%lld\n",dfs(1,m));
    return 0;
}

T3超级书架

此题考虑第t+1头奶牛选还是不选,递归调用身高累加和。

#include<bits/stdc++.h>
using namespace std;
const long long maxn=2000000000;
long long n,b,a[50];
inline int read()
{
    int num=0,flag=1;
    char c=getchar();
    for (;c<'0'||c>'9';c=getchar())
    if (c=='-') flag=-1;
    for (;c>='0'&&c<='9';c=getchar())
    num=(num<<3)+(num<<1)+c-48;
    return num*flag;
}
long long dfs(long long k,long long t)
{
    if (k>=b) return k;//边界
    if (t==n) return maxn;//边界
    return min(dfs(k,t+1),dfs(k+a[t+1],t+1));
}
int main()
{
    n=read();
    b=read();
    for (int i=1;i<=n;++i)
    a[i]=read();
    printf("%lld\n",dfs(0,0)-b);
    return 0;
}

T4集合划分问题

这个递归也有点迷,不过后来看了题解还能理解。dfs(x-1,y-1)表示把当前数单独分在一个集合,y*dfs(x-1,y)表示把当前数加入其它的一个集合中,但是有y种情况,所以要*y。

#include<bits/stdc++.h>
using namespace std;
long long n,m,f[1010][1010];
inline int read()
{
    int num=0,flag=1;
    char c=getchar();
    for (;c<'0'||c>'9';c=getchar())
    if (c=='-') flag=-1;
    for (;c>='0'&&c<='9';c=getchar())
    num=(num<<3)+(num<<1)+c-48;
    return num*flag;
}
long long dfs(long long x,long long y)
{
    if (f[x][y]>=0) return f[x][y];//记忆化搜索
    if (x==1||y==1||x==y) return 1;//边界
    if (x<y) return 0;//越界
    return f[x][y]=dfs(x-1,y-1)+y*dfs(x-1,y);
}
int main()
{
    n=read();
    m=read();
    memset(f,-1,sizeof(f));
    f[1][1]=1;
    printf("%lld\n",dfs(n,m));
    return 0;
}

T5倒牛奶

此题真的是要考虑——大的6种情况(a->b a->c b->a b->c c->a c->b),每种大的又有小的2种情况(被灌桶装满或原桶空了)。然后打得仔细一点就好啦。

#include<bits/stdc++.h>
using namespace std;
long long a,b,c,sum;
bool d[50],f[50][50][50];
inline int read()
{
    int num=0,flag=1;
    char c=getchar();
    for (;c<'0'||c>'9';c=getchar())
    if (c=='-') flag=-1;
    for (;c>='0'&&c<='9';c=getchar())
    num=(num<<3)+(num<<1)+c-48;
    return num*flag;
}
void dfs(long long x,long long y,long long z)
{
    if (f[x][y][z]) return;//记忆化搜索
    f[x][y][z]=true;
    if (x>0&&y<b)
    {
        if (x>=b-y) dfs(x-(b-y),b,z);
        else dfs(0,y+x,z);
    }
    if (x>0&&z<c)
    {
        if (x>=c-z) dfs(x-(c-z),y,c);
        else dfs(0,y,z+x);
    }
    if (y>0&&x<a)
    {
        if (y>=a-x) dfs(a,y-(a-x),z);
        else dfs(x+y,0,z);
    }
    if (y>0&&z<c)
    {
        if (y>=c-z) dfs(x,y-(c-z),c);
        else dfs(x,0,z+y);
    }
    if (z>0&&x<a)
    {
        if (z>=a-x) dfs(a,y,z-(a-x));
        else dfs(x+z,y,0);
    }
    if (z>0&&y<b)
    {
        if (z>=b-y) dfs(x,b,z-(b-y));
        else dfs(x,y+z,0);
    }
    if (x==0) d[z]=true;
}
int main()
{
    a=read();
    b=read();
    c=read(); 
    dfs(0,0,c);
    for (int i=0;i<=20;++i)
    if (d[i]) sum++;
    for (int i=0;i<=20;++i)
    if (d[i])
    {
        sum--;
        if (sum>0) printf("%d ",i);
        else printf("%d\n",i);
    }
    return 0;
}

T6整数划分

此题至今比较懵逼,我觉得它思维难度有点高,要考虑四种情况,我连最基本的递归式都写不出来。一开始还是用深搜写的。dfs(x-y,y)表示和为x的累加和中包含最大值y,dfs(x,y-1)表示不包含y。

#include<bits/stdc++.h>
using namespace std;
long long n,f[10][10];
inline int read()
{
    int num=0,flag=1;
    char c=getchar();
    for (;c<'0'||c>'9';c=getchar())
    if (c=='-') flag=-1;
    for (;c>='0'&&c<='9';c=getchar())
    num=(num<<3)+(num<<1)+c-48;
    return num*flag;
}
long long dfs(long long x,long long y)
{
    if (f[x][y]>=0) return f[x][y];//记忆化搜索
    if (x==1||y==1) return 1;//边界
    if (x<y) return f[x][y]=dfs(x,x);//越界
    if (x==y) return f[x][y]=dfs(x,y-1)+1;//特判
    return f[x][y]=dfs(x-y,y)+dfs(x,y-1);
}
int main()
{
    n=read();
    memset(f,-1,sizeof(f));
    f[1][1]=1; 
    printf("%lld\n",dfs(n,n));
    return 0;
}

T7 2的幂次方

#include<bits/stdc++.h>
using namespace std;
long long n,a[50];
inline int read()
{
    int num=0,flag=1;
    char c=getchar();
    for (;c<'0'||c>'9';c=getchar())
    if (c=='-') flag=-1;
    for (;c>='0'&&c<='9';c=getchar())
    num=(num<<3)+(num<<1)+c-48;
    return num*flag;
}
void dfs(long long k)
{
    if (k==0) return;
    if (k==1)
    {
        printf("2(0)");
        return;
    }
    if (k==2)
    {
        printf("2");
        return;
    }
    if (k==3)
    {
        printf("2+2(0)");
        return;
    }
    if (k==4)
    {
        printf("2(2)");
        return;
    }
    int t=1;
    while ((1<<t)<=k) t++;
    printf("2(");
    dfs(t-1);
    printf(")");
    if (k!=(1<<(t-1))) printf("+");
    dfs(k-(1<<(t-1)));
}
int main()
{
    n=read(); 
    dfs(n);
    return 0;
}

T8美国血统

#include<bits/stdc++.h>
using namespace std;
string a,b; 
inline int read()
{
    int num=0,flag=1;
    char c=getchar();
    for (;c<'0'||c>'9';c=getchar())
    if (c=='-') flag=-1;
    for (;c>='0'&&c<='9';c=getchar())
    num=(num<<3)+(num<<1)+c-48;
    return num*flag;
}
void dfs(int l1,int r1,int l2,int r2)
{
    if (l1>r1||l2>r2) return;
    for (int i=l1;i<=r1;++i)
    if (a[i]==b[l2])
    {
        dfs(l1,i-1,l2+1,i-l1+l2);
        dfs(i+1,r1,i-r1+r2+1,r2);
    }
    printf("%c",b[l2]);
}
int main()
{
    getline(cin,a);
    getline(cin,b);
    dfs(0,a.size()-1,0,b.size()-1);
    return 0;
}

T9椰子

毒瘤题。坑。还没2次敲过

猜你喜欢

转载自blog.csdn.net/zjh_2017/article/details/79829453
4.5