• BZOJ 2021 [Usaco2010 Jan]Cheese Towers:dp + 贪心


    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2021

    题意:

      John要建一个奶酪塔,高度最大为m。

      他有n种奶酪。第i种高度为h[i](一定是5的倍数),价值为w[i]。

      一块高度>=t的奶酪被称为大奶酪,一个奶酪如果在它上方有大奶酪(多块只算一次),它的高度就会变成原来的4/5。

      John想让他的奶酪他价值和最大,求这个最大值。

    题解:

      方法一:

        dp + 贪心。

        贪心:如果奶酪塔中有大奶酪,则大奶酪一定放在最上面。

        (1)有大奶酪时:

          枚举放在最上面的大奶酪k。

          然后将所有奶酪的高度看作h[i]*4/5,塔的最大高度为m-h[k],跑一遍完全背包。

          每一次的答案 = 完全背包的答案 + w[k],取最大。

        (2)没大奶酪时:

          最后再跑一遍没有大奶酪的完全背包,取最大。

      方法二:

        分成两种情况分别处理:

          (1)塔中有大奶酪:

            dp[i]表示高度为i,有大奶酪时的最大价值。

            初始值:

              先将dp设为-INF。

              然后对于所有的大奶酪i,dp[h[i]] = max w[i]。

            然后将所有高度看作原来的4/5,跑一遍完全背包。

          (2)没有大奶酪:

            高度为原先的高度,直接跑完全背包。

        对于两种情况取最大就好。

    AC Code(1):

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <algorithm>
     5 #define MAX_N 105
     6 #define MAX_M 1005
     7 
     8 using namespace std;
     9 
    10 int n,m,t;
    11 int ans=0;
    12 int w[MAX_N];
    13 int h[MAX_N];
    14 int dp[MAX_M];
    15 
    16 void read()
    17 {
    18     cin>>n>>m>>t;
    19     for(int i=0;i<n;i++)
    20     {
    21         cin>>w[i]>>h[i];
    22     }
    23 }
    24 
    25 int cal_dp(int m,int u,int d)
    26 {
    27     int best=0;
    28     memset(dp,0,sizeof(dp));
    29     for(int i=0;i<n;i++)
    30     {
    31         for(int j=h[i]*u/d;j<=m;j++)
    32         {
    33             dp[j]=max(dp[j],dp[j-h[i]*u/d]+w[i]);
    34             best=max(best,dp[j]);
    35         }
    36     }
    37     return best;
    38 }
    39 
    40 void solve()
    41 {
    42     for(int i=0;i<n;i++)
    43     {
    44         if(h[i]>=t) ans=max(ans,cal_dp(m-h[i],4,5)+w[i]);
    45     }
    46     ans=max(ans,cal_dp(m,1,1));
    47 }
    48 
    49 void print()
    50 {
    51     cout<<ans<<endl;
    52 }
    53 
    54 int main()
    55 {
    56     read();
    57     solve();
    58     print();
    59 }

    AC Code(2):

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #define MAX_N 105
     5 #define MAX_M 1005
     6 
     7 using namespace std;
     8 
     9 int n,m,t;
    10 int ans=0;
    11 int w[MAX_N];
    12 int h[MAX_N];
    13 int dp[MAX_M];
    14 
    15 void read()
    16 {
    17     cin>>n>>m>>t;
    18     for(int i=0;i<n;i++)
    19     {
    20         cin>>w[i]>>h[i];
    21     }
    22 }
    23 
    24 int cal_dp(int u,int d)
    25 {
    26     int best=0;
    27     for(int i=0;i<n;i++)
    28     {
    29         for(int j=h[i]*u/d;j<=m;j++)
    30         {
    31             dp[j]=max(dp[j],dp[j-h[i]*u/d]+w[i]);
    32             best=max(best,dp[j]);
    33         }
    34     }
    35     return best;
    36 }
    37 
    38 void solve()
    39 {
    40     memset(dp,0x80,sizeof(dp));
    41     for(int i=0;i<n;i++)
    42     {
    43         if(h[i]>=t) dp[h[i]]=max(dp[h[i]],w[i]);
    44     }
    45     ans=max(ans,cal_dp(4,5));
    46     memset(dp,0,sizeof(dp));
    47     ans=max(ans,cal_dp(1,1));
    48 }
    49 
    50 void print()
    51 {
    52     cout<<ans<<endl;
    53 }
    54 
    55 int main()
    56 {
    57     read();
    58     solve();
    59     print();
    60 }
  • 相关阅读:
    Linux中$含义
    Linux文本处理之grep
    MySQL8.0.15的安装与配置---win10
    Jenkins实现自动运行jmeter脚本
    Hystrix初识
    Feign初始
    AS的Gradle下载不成功
    Linux安装一些软件
    OAuth2初识
    IDEA无法打开等奇异问题终极解决方法
  • 原文地址:https://www.cnblogs.com/Leohh/p/7625896.html
Copyright © 2020-2023  润新知