zoukankan      html  css  js  c++  java
  • 基础dp 记录

    51nod 1134 最长递增子序列

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define rep(i,l,r) for (int i=l; i<=r; i++)
    typedef long long ll;
    using namespace std;
    const int N = 5e4+10;
    int n, s[N];
    int dp[N];
    
    int main(){
        freopen("in.txt","r",stdin);
        //freopen("a.out","w",stdout);
        
        scanf("%d",&n);
        for(int i=1;i<=n;i++) 
            scanf("%d", &s[i]);
        memset(dp,0x3f,sizeof(dp));
        for(int i=1;i<=n;i++) {
            int l = lower_bound(dp+1,dp+1+N,s[i])-(dp);
            dp[l] = s[i];  
        }
        int ans = lower_bound(dp+1,dp+1+N,0x3f3f3f3f)-dp -1;
        cout << ans<<endl;
        return 0;
    }

    51nod 1050 循环数组最大子段和

    考虑 成环的一个最大字段和 要么是正常的字段和 要么是整个环的总和 - (负的最大的 最小子段和)

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 5e4+10;
    int a[maxn],b[maxn],n;
    typedef long long ll;
    
    ll solve (int *s)
    {
        ll ans =0,res =0;
        for(int i=0;i<n;i++)
        {
            ans+=s[i];
            res = max(res,ans);
            if(ans < 0)
                ans =0;
        }
        return res;
    }
    
    int main ()
    {
    
        scanf("%d",&n);
        ll res=0;
        for(int i=0;i<n;i++)
        {
             scanf("%d",&a[i]);
             b[i] = -a[i];
             res += a[i];
        }
        ll ans1= solve(a),ans2=solve(b);
        res= max(ans1,res+ans2);
        printf("%lld
    ",res);
        return 0;
    }

    51nod 1183 编辑距离 

    dp[i][j] 表示s1[i]和s2[j] 匹配好的,最小需要的花费

    所以 dp[i][j] = min ( dp[i-1][j] + 1 //把s1[i] 删除 或者 添加s2[j]

             dp[i][j-1] + 1 //把s2[j] 删除 或者 添加 s1[i]

             dp[i-1][j-1]  + (s1[i]==s2[j]) // 是否需要修改 

    #include <iostream>
    #include <cstring>
    #include <string.h>
    using namespace std;
    char s1[1010],s2[1010];
    
    int dp[1010][1010];
    
    int min(int a,int b,int c) {
        if(b < a)
            a = b;
        return min(a,c);
    }
    
    int main () {
        scanf("%s %s", s1+1, s2+1);
        int l1 = strlen(s1+1);
        int l2 = strlen(s2+1);
        memset(dp,0x3f,sizeof(dp));
        for(int i=0;i<=l1;i++)
            dp[i][0] = i;
        for(int i=0;i<=l2;i++) 
            dp[0][i] = i;
    
        for(int i=1; i<=l1; i++) {
            for(int j=1; j<=l2; j++) {
                dp[i][j] = min(dp[i-1][j]+1, 
                    dp[i][j-1]+1, 
                    (dp[i-1][j-1]+(s1[i]!=s2[j]?1:0)));
                //printf("%d ",dp[i][j]);
            }
            //puts("");
        }
        cout << dp[l1][l2] <<endl;
        return 0;
    }

     51nod 1051 最大子矩阵和

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int N = 510;
    int n,m;
    ll s[N][N], sum[N][N];
    
    int main ()
    {
        scanf("%d %d", &m, &n);
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=m;j++) {
                scanf("%lld", &s[i][j]);
            }
        }
        //保存每行的信息
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=m;j++) {
                sum[i][j] = sum[i][j-1] + s[i][j];
            }
        }
        ll mx = 0;
        for(int len=1;len<=m;len++) {
            for(int i=1;i+len-1<=m;i++) { //[i,j]i列到j列
                int j = i+len-1;
                ll ans = 0;
                ll res = 0;
                for(int k=1;k<=n;k++) {
                    //mx = max();
                    ans += sum[k][j] - sum[k][i-1];
                    if(res < ans) res = ans;
                    if(ans < 0 ) ans=0;
                }
                mx = max(res,mx);
            }
        }
        cout << mx <<endl;
        return 0;
    }

    51nod 1086 背包问题 V2 

    #include <bits/stdc++.h>
    using namespace std;
    
    const int MAXW = 50000+10;
    const int N = 1100;
    typedef long long ll;
    ll dp[MAXW];
    int v[N],val[N],cnt[N];//体积 价值 数量
    
    int n,w;
    int main () {
        //freopen("in.txt","r",stdin);
        scanf("%d %d", &n, &w);
        for(int i=1;i<=n;i++) {
            scanf("%d %d %d", &v[i], &val[i], &cnt[i]);
        }
        for(int i=1;i<=n;i++) {
            if(cnt[i]*v[i]>= w) {
                for(int j=v[i]; j<=w; j++) {
                    dp[j] = max(dp[j], dp[j-v[i]] + val[i]);
                }
            }else {
                int k=1, tot = cnt[i];
                while(k<tot) {
                    for(int j=w; j>=k*v[i]; j--) {
                        dp[j] = max(dp[j], dp[j-k*v[i]]+k*val[i]);
                    }
                    tot-=k;
                    k<<=1;
                }
                for(int j=w;j>=tot*v[i];j--) {
                    dp[j] = max(dp[j], dp[j-tot*v[i]]+val[i]*tot);
                }
            }
        }
        cout << dp[w] <<endl;
        return 0;
    }

     51nod 1101 换零钱

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int mod = 1e9+7;
    const int N = 100010;
    int coin[] ={1,2,5,10,20,50,100,200,500,1000,2000,5000,10000};
    ll dp[N];
    
    
    int main () {
        int n;
        scanf("%d",&n);
        dp[0] =1;
        for(int i=0; i<13; i++) {
            for(int j=coin[i]; j<=n; j++) {
                dp[j] = (dp[j] + dp[j-coin[i]])%mod;
            }
        }
        cout << dp[n] <<endl;
        return 0;
    }

     51nod 1270 数组的最大代价

    dp[i][0] : 表示当前A[i] 为1的最大代价

    dp[i][1] : 表示当前A[i] 为B[i]的最大代价

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int N =50000+10;
    
    ll b[N],dp[N][2];
    
    
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%lld",&b[i]);
        for(int i=2;i<=n;i++) {
            dp[i][0] = max(abs(1-1)+dp[i-1][0], abs(1-b[i-1])+dp[i-1][1]);
            dp[i][1] = max(abs(b[i]-1)+dp[i-1][0], abs(b[i]-b[i-1])+dp[i-1][1]);
        }
        cout << max(dp[n][1], dp[n][0])<<endl;
    }
  • 相关阅读:
    Windows Server 2003 SP2(32位) 中文版 下载地址 光盘整合方法
    用Recycle()方法对Java对象的重要性
    Lotus中千奇百怪的 $$
    Developing a simple application using steps "User Decision" and "Mail"(1) 沧海
    沟通中的情绪管理(演讲稿) 沧海
    人只有在压力之下,才可能成功,没做一件事,都必须成功,不许言败 沧海
    什么是IDOC,以及IDOC的步骤 沧海
    VS2008 Professional Edition CHS中的deffactory.dat读取错误 沧海
    Including custom text in the step "User Decision" 沧海
    SAP Upgrade Strategy 沧海
  • 原文地址:https://www.cnblogs.com/Draymonder/p/9533218.html
Copyright © 2011-2022 走看看