• Codeforces Round #552 (Div. 3) F题


    题目网址:http://codeforces.com/contest/1154/problem/F

    题目大意:给出n,m,k,n是物体的个数,m是优惠方式的种数,k是需要购买的物体个数,

    然后给出n个数,即每个物体的价格,再给出m行,每行x,y,表示一种优惠方式,即,当你购买x

    个物体时,前y个最便宜的物体免费,问,只有一种优惠方式时,需要花费的最少的钱。

    题解:首先,要买k个物体,显然选择的物体价格是前k个最小的数,然后再考虑优惠,那么,购买k

    个物体的最小价格是总价格减去购买前k个物体的最大花费,设dp1 [ i ] 是购买前i个物体的最大优惠,

    那么在这i个物体中就可以考虑题目给的优惠方式了,设dp2[ i ]是购买了i个物体,最多可以减少物体的数量

    那么对于前i个物体,优惠就是dp1[ i ]和dp1[ j ]+s[ j + dp2[ i - j ] ] - s[ j ]),sum这里是 i - j这部分物体的价钱,因为

    我买了前j个物体,此时最大优惠是dp1[ j ],然后剩下的 i - j个物体的优惠是可以减少dp2[ i - j ]个物体的数量

    所以剩下的 i - j个 物体只需s[ j + dp2[ i - j ] ] - s[ j ],最后总价格减去最大优惠价格即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=2e5+7;
     4 int a[maxn],s[maxn],dp1[maxn],dp2[maxn];
     5 int main()
     6 {
     7     int n,m,k,x,y;
     8     cin>>n>>m>>k;
     9     memset(dp1,0,sizeof(dp1));
    10     memset(dp2,0,sizeof(dp2));
    11     for(int i=1;i<=n;i++)
    12     {
    13         scanf("%d",&a[i]);
    14     }
    15     for(int i=1;i<=m;i++)
    16     {
    17         scanf("%d %d",&x,&y);
    18         if(x<=k) dp2[x]=max(dp2[x],y);
    19     }
    20     sort(a+1,a+1+n);
    21     for(int i=1;i<=k;i++) s[i]=s[i-1]+a[i];
    22     for(int i=1;i<=k;i++)
    23     {
    24         for(int j=0;j<i;j++)
    25         {
    26             dp1[i]=max(dp1[i],dp1[j]+s[j+dp2[i-j]]-s[j]);
    27         }
    28     }
    29     cout<<s[k]-dp1[k]<<endl;
    30     return 0;
    31 }
    View Code
  • 相关阅读:
    偶串_牛客网
    制造回文_牛客网
    字典树(前缀树)的实现
    动态规划LeetCode174地下城游戏
    动态规划LeetCode64最小路径和
    动态规划LeetCode300最长上升子序列
    动态规划LeetCode120三角形最小路径和
    Zabbix 监控sqlserver
    如何回收VCSA 6自带的vPostgres数据库空间
    领益科技:导出Wireless组中的成员
  • 原文地址:https://www.cnblogs.com/duxing201806/p/10726762.html
Copyright © 2020-2023  润新知