zoukankan      html  css  js  c++  java
  • 普通dp总结

    传纸条

    从(1,1)传纸条到(m,n),经过后返回时不能经过

    四维dp,f[i][j][k][p]表示从(i,j)到(k,p)的答案,显然

    f[i][j][k][p]=max(f[i-1][j][k-1][p],max(f[i-1][j][k][p-1],max(f[i][j-1][k-1][p],f[i][j-1][k][p-1])))+a[i][j]+a[k][p]

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int maxn=55;
    inline int read(){
        int x=0,k=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') k=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
        return k*x;
    }
    int a[maxn][maxn],f[maxn][maxn][maxn][maxn];
    int main(){
    //    freopen(".in","r",stdin);
    //    freopen(".out","w",stdout);
        int n,m;
        n=read();m=read();
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                a[i][j]=read();
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                for(int k=1;k<=n;k++)
                    for(int p=j+1;p<=m;p++){
                        f[i][j][k][p]=max(f[i-1][j][k-1][p],max(f[i-1][j][k][p-1],max(f[i][j-1][k-1][p],f[i][j-1][k][p-1])))+a[i][j]+a[k][p];
                    }
        cout<<f[n][m-1][n-1][m];
        return 0;
    }
    View Code

    扫雷

    两列扫雷方格,给第二列数字,问第一列有几种可能

    本来是dp的但是太水了,最多的情况是第一个是1,则最多有2种,在依次判断一下,不符合的减去就行了

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int maxn=10005;
    inline int read(){
        int x=0,k=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') k=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
        return k*x;
    }
    int a[maxn],b[maxn],ans=2;
    void pd(int n){
        for(int i=2;i<=n+1;i++){
            b[i]=a[i-1]-b[i-1]-b[i-2];
            if(b[i]!=1&&b[i]!=0){
                ans--;
                break;
            }
            if(i==n+1&&b[i]!=0) ans--;
        }
    }
    int main(){
    //    freopen(".in","r",stdin);
    //    freopen(".out","w",stdout);
        int n;
        n=read();
        for(int i=1;i<=n;i++) a[i]=read();
        b[1]=0;pd(n);
        b[1]=1;pd(n);
        cout<<ans;
        return 0;
    }
    View Code

    数列_NOI导刊2010提高(06)

    一串数,擦去一些,问a[i]=i的最多有多少

    f[i][j]表示前i个数有j个数保留的答案,则若a[i]=j时,满足条件,则f[i][j]=max(f[i-1][j],f[i-1][j-1]+1),否则f[i][j]=max(f[i-1][j],f[i-1][j-1])

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int maxn=1005;
    inline int read(){
        int x=0,k=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') k=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
        return k*x;
    }
    int f[maxn][maxn],a[maxn];
    int main(){
    //    freopen(".in","r",stdin);
    //    freopen(".out","w",stdout);
        int n,ans=0;
        n=read();
        for(int i=1;i<=n;i++) a[i]=read();
        for(int i=1;i<=n;i++)
            for(int j=i;j;j--){
                if(a[i]==j) f[i][j]=max(f[i-1][j],f[i-1][j-1]+1);
                else f[i][j]=max(f[i-1][j],f[i-1][j-1]);
            }
        for(int i=1;i<=n;i++){
            ans=max(ans,f[n][i]);
        }
        cout<<ans;
        return 0;
    }
    View Code
  • 相关阅读:
    在一个字符串中找到第一个只出现一次的字符
    声明数组变量/// 计算所有元素的总和/打印所有元素总和/输出/foreach循环/数组作为函数的参数/调用printArray方法打印
    intellij idea 如何更改编辑器文本字体和大小
    称砝码算法//输入与算法分开
    invalid types 'int[int]' for array subscript// EOF 输入多组数据//如何键盘输入EOF
    scanf和gets的差别
    输入3行字符串/定义flag/while/字符串后要加空格符
    ‘'的单引号/输入字符串/输出单个字符
    窗口迅速关闭的解决办法/scanf/if/for/break
    【笔记】【VSCode】Windows下VSCode编译调试c/c++
  • 原文地址:https://www.cnblogs.com/silent-pyb/p/9665102.html
Copyright © 2011-2022 走看看