zoukankan      html  css  js  c++  java
  • [洛谷P1417 烹调方案]贪心+dp

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3211
    Dream City

    Time Limit: 1 Second      Memory Limit: 32768 KB

    JAVAMAN is visiting Dream City and he sees a yard of gold coin trees. There are n trees in the yard. Let's call them tree 1, tree 2 ...and tree n. At the first day, each tree i has ai coins on it (i=1, 2, 3...n). Surprisingly, each tree i can grow bi new coins each day if it is not cut down. From the first day, JAVAMAN can choose to cut down one tree each day to get all the coins on it. Since he can stay in the Dream City for at most m days, he can cut down at most m trees in all and if he decides not to cut one day, he cannot cut any trees later. (In other words, he can only cut down trees for consecutive m or less days from the first day!)

    Given nmai and bi (i=1, 2, 3...n), calculate the maximum number of gold coins JAVAMAN can get.

    Input

    There are multiple test cases. The first line of input contains an integer T (T <= 200) indicates the number of test cases. Then T test cases follow.

    Each test case contains 3 lines: The first line of each test case contains 2 positive integers n and m (0 < m <= n <= 250) separated by a space. The second line of each test case contains npositive integers separated by a space, indicating ai. (0 < ai <= 100, i=1, 2, 3...n) The third line of each test case also contains n positive integers separated by a space, indicating bi. (0 < bi<= 100, i=1, 2, 3...n)

    Output

    For each test case, output the result in a single line.

    Sample Input

    2
    2 1
    10 10
    1 1
    2 2
    8 10
    2 3

    Sample Output

    10
    21

    Hints:
    Test case 1: JAVAMAN just cut tree 1 to get 10 gold coins at the first day.
    Test case 2: JAVAMAN cut tree 1 at the first day and tree 2 at the second day to get 8 + 10 + 3 = 21 gold coins in all

    题意:你可以在m天每天砍掉一棵树,在第Q天砍掉的树w获得的价值=a[w]+b[w]*(Q-1),求能获得的最大价值。

    题解:容易想到转移方程为dp[i][j]=max(dp[i][j],dp[i-1][j-1]+p[i].b*(j-1)+p[i].a);,但是由于转移方程中有一个变量的贡献和天数有关即p[i].b,所以可以贪心地想到应该让p[i].b大的排在后面进行更新,所以排序之后进行dp即可

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 using namespace std;
     6 typedef long long ll;
     7 const int maxn=1e4+5;
     8 ll dp[255][255];
     9 struct pot{
    10     ll a;
    11     ll b;
    12 }p[255];
    13 bool cmp(struct pot aa,struct pot bb){
    14     return aa.b<bb.b;
    15 }
    16 int main(){
    17     int t;
    18     cin>>t;
    19     while(t--){
    20         int n,m;
    21         scanf("%d%d",&n,&m);
    22         for(int i=1;i<=n;i++)scanf("%lld",&p[i].a);
    23         for(int i=1;i<=n;i++)scanf("%lld",&p[i].b);
    24         memset(dp,0,sizeof(dp));
    25         sort(p+1,p+1+n,cmp);
    26         ll ans=0;
    27         for(int i=1;i<=n;i++){
    28            for(int j=1;j<=m;j++){
    29                 dp[i][j]=dp[i-1][j];
    30                 dp[i][j]=max(dp[i][j],dp[i-1][j-1]+p[i].b*(j-1)+p[i].a);
    31            }
    32         }
    33         printf("%lld
    ",dp[n][m]);
    34     }
    35     return 0;
    36 }
    View Code

    https://www.luogu.org/problemnew/show/P1417

    一共有n件食材,每件食材有三个属性,ai,bi和ci,如果在t时刻完成第i样食材则得到ai-t*bi的美味指数,用第i件食材做饭要花去ci的时间。

    众所周知,gw的厨艺不怎么样,所以他需要你设计烹调方案使得美味指数最大

    输入格式:

    第一行是两个正整数T和n,表示到达地球所需时间和食材个数。

    下面一行n个整数,ai

    下面一行n个整数,bi

    下面一行n个整数,ci

    输出格式:

    输出最大美味指数

    输入样例#1: 
    74 1
    502
    2
    47
    
    输出样例#1:
    408

    【数据范围】

    对于40%的数据1<=n<=10

    对于100%的数据1<=n<=50

    所有数字均小于100,000

    题解:容易想到转移方程为dp[j]=max(dp[j],dp[j-p[i].c]+p[i].a-j*p[i].b);其中两个变量的贡献和天数有关即p[i].b,p[i].c,两种食材设为A,B 则他们排列为AB时的贡献为-(p[A].c+p[B].c)*p[B].b-p[A].c*p[A].b,他们排列为BA时的贡献为-(p[A].c+p[B].c)*p[A].b-p[B].c*p[B].b,当(p[A].c+p[B].c)*p[B].b-p[A].c*p[A].b<-(p[A].c+p[B].c)*p[A].b-p[B].c*p[B].b时,排列为AB比BA更优,化简之后就是p[A].c*p[B].b<p[A].b*p[B].c,所以可以以此排序,然后dp

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<vector>
     6 using namespace std;
     7 typedef long long ll;
     8 ll dp[100005];
     9 struct pot{
    10     ll a;
    11     ll b;
    12     ll c;
    13 }p[55];
    14 bool cmp(struct pot ab,struct pot ba){
    15     return (ab.c*ba.b<ab.b*ba.c);
    16 }
    17 int main(){
    18     int t,n;
    19     scanf("%d%d",&t,&n);
    20     for(int i=1;i<=n;i++)scanf("%lld",&p[i].a);
    21     for(int i=1;i<=n;i++)scanf("%lld",&p[i].b);
    22     for(int i=1;i<=n;i++)scanf("%lld",&p[i].c);
    23     ll ans=0;
    24     sort(p+1,p+1+n,cmp);
    25     for(int i=1;i<=n;i++){
    26         for(int j=t;j>=p[i].c;j--){
    27             //dp[j]=max(dp[j],dp[j-1]);
    28             dp[j]=max(dp[j],dp[j-p[i].c]+p[i].a-j*p[i].b);
    29             ans=max(ans,dp[j]);
    30         }
    31     }
    32     cout<<ans<<endl;
    33     return 0;
    34 }
    View Code
  • 相关阅读:
    五年微软DevOps MVP (也称TFS MVP)
    微软 Azure DevOps Server 2019 Update 1 (TFS 2019.1)
    在Azure DevOps Server (TFS)中实现VUE项目的自动打包
    Azure DevOps Server (TFS) 代码库Repo管理培训
    Azure DevOps Server 2019 第一个补丁包(2019.0.1 RTW)
    Azure DevOps Server (TFS) 修改工作项附件大小限制
    Azure DevOps Server (TFS) 修改Git文件大小限制
    字符串转换整数 (atoi) C++实现 java实现 leetcode系列(八)
    整数翻转C++实现 java实现 leetcode系列(七)
    Z 字形变换 C++实现 java实现 leetcode系列(六)
  • 原文地址:https://www.cnblogs.com/MekakuCityActor/p/10607405.html
Copyright © 2011-2022 走看看