zoukankan      html  css  js  c++  java
  • 寒假ACM集训复习总结Day3-helman

    这一天学的是贪心算法和暴力枚举

    感觉比第一天的思维题还简单,也许是因为全部列出来是人的普遍想法吧

    那就放几个经典例题吧

    HDU - 2037

    一道经典的看电视的问题,给出一系列节目的开始结束时间,算出你最多能看几部

    思路是要对每个节目的结束时间从小到大排序,每次选择结束时间早的不和上一个节目冲突的节目

    #include <bits/stdc++.h>
    using namespace std;
    struct tv{
        int begin;
        int end;
    }t[101];
    bool cmp(tv &a,tv &b){
        return a.end<b.end;
    }
    int main(){
        freopen("1.in","r",stdin);
        int n;
        while(cin>>n&&n){
            for(int i=0;i<n;i++)
                cin>>t[i].begin>>t[i].end;
            sort(t+0,t+n,cmp);
            int ans=1,e=t[0].end,b;
            for(int i=1;i<n;i++){
                b=t[i].begin;
                if(b<e)continue;
                ans++;
                e=t[i].end;
            }
            cout<<ans<<endl;
        }
        return 0;
    }

    又是一道经典例题,数塔问题,这里分成两个方法求解

    HDU - 2084

    第一种是通过分析后,我们采用动态分析的思想,从下到上,每次都选择下一行里最大的数相加,代码如下

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e4+7;
    int main(){
        freopen("1.in","r",stdin);
        int c,n;
        int m[101][101];
        cin>>c;
        while(c--){
            cin>>n;
            for(int i=1;i<=n;i++)
                for(int j=1;j<=i;j++)
                    cin>>m[i][j];
            for(int i=n-1;i>=1;i--){
                for(int j=1;j<=n-1;j++)
                    m[i][j]+=max(m[i+1][j],m[i+1][j+1]);
            }
            cout<<m[1][1]<<endl;
        }
        return 0;
    }

    第二种方法是从上到下,这种做法缺点是求每一个数时都要从塔顶开始加起,十分费时,解决方法就是建立一个数组来储存算好的数的值,这种方法叫做记忆化搜索,也叫备忘录

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e4+7;
    int m[101][101],b[101][101];
    int n;
    int bd(int i,int j){
        if(m[i][j])return m[i][j];
        if(i>n||j>n)return 0;
        m[i][j]=b[i][j]+max(bd(i+1,j),bd(i+1,j+1));
        return m[i][j];
    }
    int main(){
        //freopen("1.in","r",stdin);
        int c;
        cin>>c;
        while(c--){
            memset(m,0,sizeof(m));
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
                for(int j=1;j<=i;j++)
                    scanf("%d",&b[i][j]);
            cout<<bd(1,1)<<endl;
        }
        return 0;
    }
  • 相关阅读:
    mac 10.15.7 修改PATH
    oc 属性类型一般用法
    ubuntu解压zip文件名乱码
    telnet 退出
    docker 根据容器创建镜像
    mac android adb device 没有显示设备
    Yii2 查看所有的别名 alias
    Yii2 App Advanced 添加 .gitignore
    ubuntu 18.04 搜狗突然就提示乱码
    An error occured while deploying the file. This probably means that the app contains ARM native code and your Genymotion device cannot run ARM instructions. You should either build your native code to
  • 原文地址:https://www.cnblogs.com/helman/p/10464514.html
Copyright © 2011-2022 走看看