• 2020暑期培训 Day3


    A - 饭卡 (HDU - 2546)  0-1背包

    思路:

    我们肯定希望在余额大于$5$元并且最接近的时候去买那个最贵的

    所以问题就转化为只有$m-5$元,在前$n-1$低的物品中尽可能话更多的钱买

    这就转化为一个裸的$0-1$背包问题了

    #include<iostream>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    int a[1005],dp[1005],n,m;
    int main()
    {
        while(cin>>n&&n){
            for(int i=1;i<=n;i++) cin>>a[i];
            sort(a+1,a+1+n);
            cin>>m;
            if(m<5) cout<<m<<endl;
            else{
                memset(dp,0,sizeof(dp));
                for(int i=1;i<n;i++)
                    for(int j=m-5;j>=a[i];j--)
                        dp[j]=max(dp[j],dp[j-a[i]]+a[i]);
                cout<<m-dp[m-5]-a[n]<<endl;
            }
        }
        return 0;
    }
    View Code

    B - 数塔 (HDU - 2084) DP

    思路:

    DP入门题

    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int maxn=110;
    int dp[maxn][maxn],a[maxn][maxn];
    int main()
    {
        int t,n;
        cin>>t;
        while(t--){
            cin>>n;
            for(int i=1;i<=n;i++)
                for(int j=1;j<=i;j++)
                    cin>>a[i][j];
            int ans=dp[1][1]=a[1][1];
            for(int i=2;i<=n;i++){
                for(int j=1;j<=i;j++){
                    dp[i][j]=max(dp[i-1][j]+a[i][j],dp[i-1][j-1]+a[i][j]);
                    if(i==n) ans=max(dp[i][j],ans);
                }
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    View Code

    C - Bridging signals (HDU - 1950) LIS优化

    思路:

    化简题意就是求一个LIS,但是由于数据比较大,需要用数据结构或者二分来进行优化

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #define lowbit(x) (x&(-x))
     using namespace std;
     const int maxn=100100;
     int n=0,len;
     int a[maxn],mx[maxn];
     void add(int x,int val)
     {
         while(x<=maxn){
             mx[x]=max(mx[x],val);
             x+=lowbit(x);
         }
     }
     int query(int x)
     {
         int ans=0;
         while(x>=1){
             ans=max(mx[x],ans);
             x-=lowbit(x);
         }
        return ans;
     }
     int main()
     {
         int t,n;
        cin>>t;
        while(t--){
            memset(mx,0,sizeof(mx));
            cin>>n;
            for(int i=1;i<=n;i++) cin>>a[i];
            int ans=0;
             for(int i=1;i<=n;i++){
                 int x=query(a[i])+1;
                add(a[i],x);
                ans=max(ans,x); 
             }
             cout<<ans<<endl;
        } 
         return 0;
     }
    View Code

    D - 反恐训练营 (HDU - 1243) 

    思路:

    最长公共子序列变形

    #include<iostream>
    #include<algorithm>
    #include<map>
    #include<cstring>
     using namespace std;
     const int maxn=2005;
     map<char,int> m;
     string s,a,b;
     int dp[maxn][maxn];
     int main()
     {
         int n,x;
         while(scanf("%d",&n)!=EOF){
             memset(dp,0,sizeof(dp));
             m.clear();
             cin>>s;
             for(int i=0;i<n;i++){
                 cin>>x;
                 m[s[i]]=x;
             }
            cin>>a>>b;
            int len1=a.length();
            int len2=b.length();
            for(int i=0;i<len1;i++){
                for(int j=0;j<len2;j++){
                    if(a[i]==b[j])
                        dp[i+1][j+1]=dp[i][j]+m[a[i]];
                    else
                        dp[i+1][j+1]=max(dp[i][j+1],dp[i+1][j]);
                }
            }
            cout<<dp[len1][len2]<<endl;
         }
        return 0;
     }
    View Code

    E - Rescue Haibara (Gym - 101778E) 结构体排序

    思路:

    按照题意对各个安全屋进行排序就好了

    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int maxn=510;
    struct node{
     int d, m, num;
    }a[maxn];
    int cmp(struct node xx, struct node yy)
    {
     if(xx.d!=yy.d) return xx.d<yy.d;
     else if(xx.m!=yy.m) return xx.m>yy.m;
     else if(xx.num!=yy.num) return xx.num<yy.num;
     return -1;
    }
    int main()
    {
        int t,n,x,y,u,v;
        cin>>t;
        while(t--){
         int h=0;
         cin>>n>>x>>y;
         for(int i=0;i<n;i++){
            cin>>u>>v;
              if(u<=x&&v>=y){
                   a[h].num = i+1, 
                   a[h].d = u, 
                   a[h++].m = v;
              }
         }
         sort(a, a+h, cmp);
         if(h==0) printf("-1
    ");
         else printf("%d
    ",a[0].num);
        }
        return 0;
    }
    View Code

    F - Position in Fraction (CodeForces - 900B) 模拟

    思路:

    模拟除法的过程,注意及时跳出

    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long LL;
    const int maxn = 1e5+1000;
    int i,pos=-1,c;
    int main()
    {
        int fz,fm,i=0;
        cin>>fz>>fm>>c;
        while(1){
            i++;
            fz=fz*10;
            if(fz/fm==c){
                pos=i;
                break;
            }
            fz=fz%fm;
            if(i>=100005) break; 
        }
        cout<<pos;
       return 0;
    }
    View Code

    G - Merge Equal Elements (CodeForces - 926E) 模拟

    思路:

    按照题意直接模拟

    #include<iostream>
    #include<algorithm>
     using namespace std;
     const int maxn=1e6+5;
     int a[maxn];
     int main()
     {
         int n,x,k;
         cin>>n;
         for(int i=1;i<=n;i++){
             cin>>x;
             while(x==a[k]){
                 k--;
                x++;
             } 
             k++;
             a[k]=x;
         }
        cout<<k<<endl;
        for(int i=1;i<=k;i++)
            cout<<a[i]<<" ";
        return 0;
     }
    View Code

     H - Data Center Maintenance (CodeForces - 949C) Tarjan缩点

    思路:

    对于一个数据的两台机器宕机时间$t1,t2$,如果$t2=(t1+1)%h,t1=(t2+1)%h$,那么他们就会有影响,我们就应该给他们连一条边

    这样建图之后,我们用$tarjan$进行缩点,就成为了一张$DAG$图,答案就为入度为$0$,并且大小最小的联通块

    #include<iostream>
    #include<algorithm>
    #include<vector>
     using namespace std;
     const int maxn=1e5+10;
     vector<int> a[maxn];
     int tot=0,t=0,k=0;
     int dfs[maxn],low[maxn],stack[maxn],flag[maxn],color[maxn],cnt[maxn],in[maxn],tim[maxn];
     void tarjan(int x)
     {
         dfs[x]=low[x]=++tot;
         stack[++k]=x;
         flag[x]=1;
         for(int i=0;i<a[x].size();i++){
             if(!dfs[a[x][i]]){
                 tarjan(a[x][i]);
                 low[x]=min(low[x],low[a[x][i]]);
             }
            else if(flag[a[x][i]])
                low[x]=min(low[x],dfs[a[x][i]]);
         }
        if(dfs[x]==low[x]){
            t++;
            do{
                color[stack[k]]=t,cnt[t]++;
                flag[stack[k--]]=0;
            }while(x!=stack[k+1]);
        }
     }
     int main()
     {
         int n,m,h,u,v;
         scanf("%d%d%d",&n,&m,&h);
         for(int i=1;i<=n;i++) scanf("%d",&tim[i]);
         for(int i=1;i<=m;i++){
             scanf("%d%d",&u,&v);
             if(tim[u]==(tim[v]+1)%h) a[u].push_back(v);
             if(tim[v]==(tim[u]+1)%h) a[v].push_back(u);
         }
        for(int i=1;i<=n;i++)
            if(!dfs[i]) tarjan(i);
        for(int i=1;i<=n;i++){
            for(int j=0;j<a[i].size();j++){
                int v=a[i][j];
                if(color[i]!=color[v]) in[color[v]]++;
            }
        }
        cnt[0]=n+1;
        int ans=0;
        for(int i=1;i<=t;i++)
            if(cnt[i]<cnt[ans]&&in[i]==0) ans=i;
        cout<<cnt[ans]<<endl;
        for(int i=1;i<=n;i++)
            if(color[i]==ans) cout<<i<<" ";    
        return 0;
     }
    View Code
  • 相关阅读:
    如何带平均年龄小的团队
    如何带平均年龄大的团队
    Extjs中常用表单介绍与应用
    .NET 应用架构指导 V2[17]
    一个男人的关心的东西
    微软企业库5.0学习笔记(十四)
    .NET 应用架构指导 V2[19]
    微软企业库5.0学习笔记(十五)
    计算机基本图书
    vs添加博客园精华区
  • 原文地址:https://www.cnblogs.com/overrate-wsj/p/13232903.html
Copyright © 2020-2023  润新知