zoukankan      html  css  js  c++  java
  • ZOJ 3211 Dream City

    贪心,$dp$。

    假设我们知道要选择哪些物品,那么这些物品应该按什么顺序选择呢?

    物品$A(a1,b1)$,物品$B(a2,b3)$。

    假设物品$A$在第$x$天被选择,物品$B$在第$y$天被选择。$x<y$。那么收益为:$P1=a1+(x-1)*b1+a2+(y-1)*b2$。

    假设物品$A$在第$y$天被选择,物品$B$在第$x$天被选择。$x<y$。那么收益为:$P2=a1+(y-1)*b1+a2+(x-1)*b2$。

    $P1>P2$的条件为:$(x-1)*b1+(y-1)*b2>(y-1)*b1+(x-1)*b2$,即$(y-x)*(b2-b1)>0$,即$b2>b1$。

    也就是说,假设我们知道要选择哪些物品,那么这些物品按$b$从小到大取获得的收益最大。

    因此,我们可以降物品按照$b$从小到大排序,然后去决策应该选择哪些物品,$dp$即可。

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<ctime>
    #include<iostream>
    using namespace std;
    typedef long long LL;
    const double pi=acos(-1.0);
    void File()
    {
        freopen("D:\in.txt","r",stdin);
        freopen("D:\out.txt","w",stdout);
    }
    template <class T>
    inline void read(T &x)
    {
        char c = getchar();
        x = 0;
        while(!isdigit(c)) c = getchar();
        while(isdigit(c))
        {
            x = x * 10 + c - '0';
            c = getchar();
        }
    }
    
    int T,n,m;
    
    
    struct X
    {
        int a,b;
    }s[300];
    
    bool cmp(X a, X b)
    {
        return a.b<b.b;
    }
    
    int dp[300][300];
    
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;i++) scanf("%d",&s[i].a);
            for(int i=1;i<=n;i++) scanf("%d",&s[i].b);
    
            sort(s+1,s+1+n,cmp);
    
            memset(dp,0,sizeof dp);
    
            dp[1][1]=s[1].a;
            for(int i=2;i<=n;i++) dp[i][1]=max(dp[i-1][1],s[i].a);
    
            for(int j=2;j<=m;j++)
            {
                for(int i=j;i<=n;i++)
                {
                    dp[i][j]=max(dp[i-1][j],dp[i-1][j-1]+s[i].a+(j-1)*s[i].b);
                }
            }
    
            printf("%d
    ",dp[n][m]);
    
        }
        return 0;
    }
  • 相关阅读:
    vip视频播放
    一行Python代码画心型
    使用赫夫曼编码压缩数据
    动态规划与贪婪算法学习笔记
    boost 编写finger服务
    磁盘保护原理简介
    知乎上的一道题目 如何判断某个二进制数如是否存在两位1中间有包含0的情况?
    <Linux多线程服务端编程>学习记录
    Debian8 下面 muduo库编译与使用
    无盘工作站原理分析
  • 原文地址:https://www.cnblogs.com/zufezzt/p/6401688.html
Copyright © 2011-2022 走看看