zoukankan      html  css  js  c++  java
  • 动态规划 | 1007 最大连续子序列和

    本题是对“ 最大连续子序列和”这个问题的变形,只要读懂题,处理好细节,没有什么设坑的地方。

    这道题可以用贪心和DP来做,我开始用贪心做的,wa了一个测试点。经过了一波冷静的分析,查出了原因,AC了。

    贪心

    贪心的思路很简单,遍历一遍数组,用mA记录最优解的第一个数,用mB记录最优解的第二个数,mSum记录最优解,a、b、sum都是临时变量。

    一下加粗的代码是漏打的bug:

    #include <stdio.h>
    #include <memory.h>
    #include <math.h>
    #include <string>
    #include <vector>
    #include <set>
    #include <stack>
    #include <queue>
    #include <algorithm>
    #include <map>
    
    
    #define I scanf
    #define OL puts
    #define O printf
    #define F(a,b,c) for(a=b;a<c;a++)
    #define FF(a,b) for(a=0;a<b;a++)
    #define FG(a,b) for(a=b-1;a>=0;a--)
    #define LEN 100000
    #define MAX (1<<30)-1
    #define V vector<int>
    
    using namespace std;
    
    int num[LEN];
    
    int main(){
    //    freopen("1007.txt","r",stdin);
        int i,n,t,a,b,mSum=-1,sum=0,mA,mB;
        I("%d",&n);
        FF(i,n) I("%d",&num[i]);
        a=num[0];
        FF(i,n){
            t=num[i];
            if(sum+t<0){
                sum=0;
                a=num[i+1];
            }else{
                sum+=t;
                b=t;
                if(sum>mSum){
                    mSum=sum;
                    mA=a;
                    mB=b;
                }
            }
        }
        if(mSum<0){
            O("%d %d %d",0,num[0],num[n-1]);
        }else{
            O("%d %d %d",mSum,mA,mB);
        }
        return 0;
    }

    DP

    DP的思路在注释中,这里不再赘述

    #include <stdio.h>
    #include <memory.h>
    #include <math.h>
    #include <string>
    #include <vector>
    #include <set>
    #include <stack>
    #include <queue>
    #include <algorithm>
    #include <map>
    
    
    #define I scanf
    #define OL puts
    #define O printf
    #define F(a,b,c) for(a=b;a<c;a++)
    #define FF(a,b) for(a=0;a<b;a++)
    #define FG(a,b) for(a=b-1;a>=0;a--)
    #define LEN 100000
    #define MAX (1<<30)-1
    #define V vector<int>
    
    using namespace std;
    
    int a[LEN];
    int s[LEN];    //s[i]表示dp[i]的连续序列从a的哪个元素开始的 
    int dp[LEN];//dp[i]存放以a[i]结尾的连续序列的最大和 
    
    int main(){
    //    freopen("1007.txt","r",stdin);
        int i,n;
        bool flag=0;    //数组中的元素是否全部小鱼0 
        I("%d",&n);
        FF(i,n){
            I("%d",&a[i]);
            if(a[i]>=0) flag=1;
        }
        if(!flag){
            O("%d %d %d",0,a[0],a[n-1]);
            return 0;
        }
        //边界
        dp[0]=a[0] ;
        //注意隐式赋值: s[0]=0 
        F(i,1,n){
            //状态转移方程
            if(dp[i-1]+a[i]>a[i]){    //
                dp[i]=dp[i-1]+a[i];
                s[i]=s[i-1];
            }else{                    //不放 
                dp[i] =a[i];
                s[i]=i;
            }
        }
        //遍历一遍,找到以哪个元素结尾,连续和最大
        int k=0;
        F(i,1,n) {
            if(dp[i]>dp[k]){
                k=i;
            }
        }    
        O("%d %d %d",dp[k],a[s[k]],a[k]);
        return 0;
    }
  • 相关阅读:
    算法导论课后习题解析 第六章
    算法导论课后习题解析 第二章
    如果你也是.NET程序员
    查询对象模式
    为什么要面向对象呢
    HTTP强缓存和协商缓存 F
    MFC Dialog改变大小后,控件随之改变方法
    关于C++类型萃取
    docker配置docker
    idea 全局搜索(Ctrl+Shift+F)不能使用解决办法
  • 原文地址:https://www.cnblogs.com/TQCAI/p/8569854.html
Copyright © 2011-2022 走看看