zoukankan      html  css  js  c++  java
  • 两个采药(东方化改题+xjb注释的题解)

    【问题描述】

    辉夜是个天资聪颖的少女,她的梦想是成为世界上最伟大的医师。为此,她想拜附近

    最有威望的医师永琳为师。永琳为了判断她的资质,给她出了一个难题。永琳把她带到一

    个到处都是草药的山洞里对她说:“孩子,这个山洞里有一些不同的草药,采每一株都

    需要一些时间,每一株也有它自身的价值。我会给你一段时间,在这段时间里,你可

    以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。”

    如果你是辉夜,你能完成这个任务吗?

    【输入文件】

    输入文件medic.in的第一行有两个整数T和M,用一个空格隔开,T代表总共能够用来

    采药的时间,M代表山洞里的草药的数目。接下来的M行每行包括两个整数,分别表示

    采摘某株草药的时间和这株草药的价值。

    【输出文件】

    输出文件medic.out包括一行,这一行只包含一个整数,表示在规定的时间内,可以采

    到的草药的最大总价值。如果不能完成这个任务输出“不能”。

    参考代码是:

    1 #include<cstdio>
    2 using namespace std;
    3 int main()
    4 {
    5     printf("不能");
    6     return 0;
    7 }

    啊,当然不是。                                                                                                                 

    这个题有两种数据范围,分别对应两种代码

    第一种:

    1 <= T <= 1000

    1 <= M <= 100

    对于30%的数据,M <= 10;

    对于全部的数据,M <= 100。

    这个呢就是动态规划做01背包,非常简单

     1 #include<cstdio>
     2 using namespace std;
     3 int v,p,T,M,dp[1005];
     4 int main()
     5 {
     6     freopen ("medic.in","r",stdin); 
     7     freopen ("medic.out","w",stdout);
     8     scanf("%d%d",&T,&M);
     9     for (int i=1;i<=M;i++)
    10     {
    11         scanf("%d%d",&v,&p);
    12         for (int j=T;j>=v;j--)
    13             dp[j]=max(dp[j],dp[j-v]+p);    //递推式子,j是剩余时间 
    14     }
    15     printf("%d",dp[T]);
    16     return 0;
    17 }

    总体来说背包的递推通式就是:

    1 f[j] = max(f[j],f[j-v[i]]+w[i])

    当然这是数据范围比较小的情况……

    第二种:

    50%的数据中 T,M ≤ 1000;

    100%的数据中 T,M ≤ 100000,Ti,V≤10。

    这个需要加上奇奇怪怪的优化

    我不会

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <string>
     5 #include <stdlib.h>
     6 #include <vector>
     7 #include <algorithm>
     8 #include <math.h>
     9 using namespace std;
    10 const int MAXN=100050;
    11 int box[11][11],dp[MAXN],N,M,t1,t2,er[25],ge[20];  
    12 void solve(int v,int p,int n);
    13 void solve(int v,int p,int n)
    14 {
    15     int t=n,time=0,v1,p1;
    16     memset(ge,0,sizeof(ge));
    17     for (int i=1;i<=20;i++)
    18     {
    19         if (t-er[i]>=0) 
    20         {
    21             ge[i]=er[i];
    22             t-=er[i];
    23             time=i;
    24         }
    25         else
    26         {
    27             ge[i]=t;
    28             time=i;
    29             break;
    30         }
    31     }
    32     for (int i=1;i<=time;i++)
    33     {
    34         v1=ge[i]*v;
    35         p1=ge[i]*p;
    36         for (int j=M;j>=v1;j--)
    37             dp[j]=max(dp[j],dp[j-v1]+p1);    //递推式子 
    38     }
    39 }
    40 int main()
    41 {
    42     freopen ("medic2.in","r",stdin); 
    43     freopen ("medic2.out","w",stdout);
    44     scanf("%d%d",&N,&M);
    45     er[1]=1;
    46     for (int i=2;i<=20;i++)
    47         er[i]=er[i-1]<<1;
    48     for (int i=1;i<=N;i++)
    49     {
    50         scanf("%d%d",&t1,&t2);
    51         box[t1][t2]++;
    52     }
    53     
    54     for (int i=1;i<=10;i++)
    55     {
    56         for (int j=1;j<=10;j++)
    57             if (box[i][j])
    58                 solve(i,j,box[i][j]);
    59     }
    60     printf("%d
    ",dp[M]);
    61 //    cout<<dp[M]<<endl;
    62 //    solve(1,2,box[1][2]);
    63     return 0;
    64 } 

    啊gg让我们写题解可是我不想写

  • 相关阅读:

    ATM三层架构思路
    一个项目的从无到有
    re模块
    logging模块
    物联网公共安全平台软件体系架构
    本科生怎样发表自己的论文
    Cloud Native 云化架构阅读笔记
    实验5 Spark SQL编程初级实践
    云计算环境下计算机软件系统架构分析
  • 原文地址:https://www.cnblogs.com/aristocrat/p/8496123.html
Copyright © 2011-2022 走看看