zoukankan      html  css  js  c++  java
  • HDU5526/BestCoder Round #61 (div.1)1004 Lie 背包DP

    Lie

     
     
    问题描述
    一个年级总共有N个学生,每个人属于唯一一个班级。现在他们站在一排,同班同学并不一定会站在一起,但每个人都会说一句话:“站在我左边的有Ai个同班同学,右边有Bi个同班同学”。然而并不是每个人都会说真话,老师也忘了他们说话的顺序,现在老师想知道最多有多少人的话同时不矛盾。
    
    输入描述
    输入有多组数据,不超过100组.
    每组数据第一行包含一个整数N.(1leq Nleq 1000 )(1N1000)
    随后N行,每行包含两个数字Ai和Bi.(0leq Ai,Bileq 1000 )(0Ai,Bi1000)
    输出描述
    对于每组数据输出一行答案.
    输入样例
    3
    0 2
    2 0
    3 0
    5
    0 0
    1 0
    0 0
    0 0
    0 0
    输出样例
    2
    4
     
     

    题解:根据左右边同班同学的人数可以得知其班级人数和其在班上相对位置,只有班级人数相同才可能为同一个班级,而在同一个班级的人出现矛盾的只能是班上相对位置相同。先根据班级人数排序,对于班级人数相同的统计每个相对位置上有多少人,枚举人数为x的班级有y个,当y确定的时候就可以贪心得出最大不矛盾数量。这就转化成了分组背包,最后使得挑选出来的年级人数不超过N即可。复杂度O({n}^{2})O(n2​​).

    ///1085422276
    #include<bits/stdc++.h>
    using namespace std ;
    typedef long long ll;
    #define mem(a) memset(a,0,sizeof(a))
    inline ll read()
    {
        ll x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*f;
    }
    //****************************************
    #define maxn 1999+5
    #define mod 1000000007
    struct ss{
      int l,r,s;
    }a[maxn];
    int cmp(ss s1,ss s2){
    return s1.s<s2.s;
    }int n,H[maxn];
    vector<int >G[maxn],A;
    int V[maxn];
    vector< pair<int ,int > >ans;
    int main()
    {
           while(scanf("%d",&n)!=EOF){mem(V);
            for(int i=1;i<=n;i++){
                scanf("%d%d",&a[i].l,&a[i].r);
                a[i].s=a[i].l+a[i].r+1;
           }int k=0;
           for(int i=0;i<=1000;i++)G[i].clear();
           A.clear();ans.clear();
           sort(a+1,a+n+1,cmp);
           for(int i=1;i<=n;i++){
             G[a[i].s].push_back(a[i].l+1);
             if(!V[a[i].s])
             A.push_back(a[i].s);V[a[i].s]=1;
           }mem(H);
           for(int i=0;i<A.size();i++){int maxx=0;
             for(int j=0;j<G[A[i]].size();j++){
                H[G[A[i]][j]]++;maxx=max(maxx,H[G[A[i]][j]]);
             }
             while(maxx){
                int ab=0;
              for(int j=1;j<=A[i];j++){
                if(H[j]) ab++,H[j]--;
              } 
              ans.push_back(make_pair(A[i],ab));
              maxx--;
             }
           }int dp[maxn];mem(dp);
           for(int i=0;i<ans.size();i++){
            for(int j=n;j>=ans[i].first;j--){
                dp[j]=max(dp[j],dp[j-ans[i].first]+ans[i].second);
            }
           }
           cout<<dp[n]<<endl;
           }
        return 0;
    }
    31ms
  • 相关阅读:
    NFC技术:让Android自动打开网页
    NFC技术:让Android自动运行程序
    NFC技术:概述
    路由器端口映射实现外网访问本地服务器
    Java之MySql数据库链接
    最短路径之Dijkstra算法及实例分析
    各种排序算法的时间性能比较
    C#实现基于ffmpeg加虹软的人脸识别
    虹软SDK在nodejs中的集成
    Android 虹软2.0人脸识别,注册失败问题 分析synchronized的作用
  • 原文地址:https://www.cnblogs.com/zxhl/p/4944059.html
Copyright © 2011-2022 走看看