• 2019 牛客多校 第六场


    题目链接:https://ac.nowcoder.com/acm/contest/886#question 链接

    A:

      题意:签到,读题读了好久......

    D:

      题意:给定n个物品,k个体积相等的盒子,求一个最小体积使得所有的物品都可以装到盒子里。装盒子要满足有大的就装大的,没有大的才能装小的的策略

      题解:我们要求的答案不满足:若ans成立,则ans+1成立(即不符合单调性)。

         对于下面这个样例

         15 5

         39 39 39 39 39 60 60 60 60 60 100 100 100 100 10

         199 为一个合法的答案,但 200 不是,201 也不是。

         这个数据量,直接暴力枚举ans,再判断是否满足即可。

         multiset的相关操作:https://blog.csdn.net/hlsdbd1990/article/details/46501391

                   http://c.biancheng.net/view/545.html

    #include <bits/stdc++.h>
    using namespace std;
    
    const int MAXN=1e3+5;
    int n, k, a[MAXN], vis[MAXN];
    
    bool judge1(int ans) //372ms
    {
        sort(a, a+n);
        for(int i=0; i<n; i++) vis[i]=0;
        for(int i=0; i<k; i++)
        {
            int nv=ans;
            for(int j=n-1; j>=0; j--)
            {
                if(!vis[j] && nv>=a[j])
                {
                    nv-=a[j];
                    vis[j]=1;
                }
            }
        }
        for(int i=0; i<n; i++)
                if(!vis[i]) 
                    return false;
        return true;
    }
    
    bool judge2(int ans) //310ms
    {
        multiset<int> S;
        multiset<int>::iterator it;
        for(int i=0; i<n; i++) S.insert(a[i]);
        for(int i=0; i<k; i++)
        {
            int nv=ans; 
            while(!S.empty() && (it=S.upper_bound(nv))!=S.begin())
            {
                it--;
                nv-=*it;
                S.erase(it);
            }
        }
        return S.empty();
    }
    
    int main()
    {
        ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
        int T, kase=0;
        for(cin>>T; T--; )
        { 
            cin>>n>>k;
            int sum=0, mv=0;
            for(int i=0; i<n; i++)
            {
                cin>>a[i];
                sum+=a[i];
                mv=max(mv, a[i]);
            }
            for(int ans=max(mv, (int)ceil(sum/k)); ans; ans++)
            {
                if(judge2(ans))
                {
                    cout<<"Case #"<<++kase<<": "<<ans<<endl;
                    break;
                }
            }
        }
        return 0;
    }
    View Code

    J:

      题意:有i个技能,每次从j-1级升级到j级都有花费cij,然后所有技能都达到j级(至少有一个是j级,其他的可以大于等于j级)送dj块钱(cij和dj可以是负数),问你最多能赚多少。

      题解:用st表维护升级花费矩阵的前缀和,枚举可以可以达到的等级,注意可以达到等级从0开始,建表的时候把0也带上, 求最优情况即可。复杂度:n*m*logm+n*m ,960ms

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
     
    const int MAXN=1e3+5;
    int n, m;
    ll b[MAXN], a[MAXN][MAXN], st[MAXN][MAXN][20];
      
    void make_st()
    {
        for(int i=1; i<=n; i++)
            for(int j=1; j<=m+1; j++)
                st[i][j][0]=a[i][j];
     
        for(int k=1; k<=n; k++)
            for(int j=1; (1<<j)<=m; j++)
                for(int i=0; i+(1<<j)-1<=m; i++)
                    st[k][i][j]=min(st[k][i][j-1], st[k][i+(1<<j-1)][j-1]);
    }
     
    ll ask(int i, int l, int r)
    {
        int k=log2(r-l+1);
        return min(st[i][l][k], st[i][r-(1<<k)+1][k]);
    }
     
    int main()
    {
        ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
        int T, kase=0;
        for(cin>>T; T--; )
        {
            cin>>n>>m;
            for(int i=1; i<=n; i++)
                for(int j=1; j<=m; j++)
                {
                    cin>>a[i][j];
                    a[i][j]=a[i][j]+a[i][j-1];
                }
            for(int i=1; i<=m; i++)
            {
                cin>>b[i];
                b[i]=b[i]+b[i-1];
            }
            make_st();
            ll ans=0;
            for(int i=0; i<=m; i++)
            {
                ll s1=0;
                for(int j=1; j<=n; j++)
                    s1=s1+ask(j, i, m);
                for(int j=1; j<=n; j++)
                {
                    ll s2=s1-ask(j, i, m)+a[j][i];
                    ans=max(ans, b[i]-s2);
                }
            }
            printf("Case #%d: %lld
    ", ++kase, ans);   
        }
        return 0;
    }
    View Code
  • 相关阅读:
    WCF 转 武胜
    NET(C#):GetHashCode不需要太复杂 转 武胜
    wcf KnownTypeAttribute 武胜
    memmove
    李开复谈创业失败十原因:经不住诱惑 直接山寨
    Linux使用Wine 安装source insight
    VM 中ubuntu下Eclipse ctrl+s 显示update conflict的问题
    ISO/OSI模型
    memset函数使用详解
    C语言中字符串的处理方式
  • 原文地址:https://www.cnblogs.com/Yokel062/p/11305932.html
Copyright © 2020-2023  润新知