• 寒假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;
    }
  • 相关阅读:
    C#中两个不同时间的相加减以及时间比较
    C#中一些报错处理
    C#将DataGridView中的数据导出为EXCEL
    C# tabcontrol的tabpage切换
    C# DataGridView控件中数据导出到Excel
    C#将数据导入到excel中 出现 “object”未包含“get_Range”的定义
    SQL Server数据库的备份与还原以及在项目中是怎样去实现的 (网摘)
    android各组件详解
    刚刚做得一个Android开发教程的专题
    一个Demo让你掌握所有的android控件
  • 原文地址:https://www.cnblogs.com/helman/p/10464514.html
Copyright © 2020-2023  润新知