采药(经典问题)

题目描述

辰辰是个很有潜能、天资聪颖的孩子,他的梦想是称为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。”

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

输入格式

输入的第一行有两个整数$T\left ( 1\leqslant T\leqslant 100\right )$和$M\left ( 1\leqslant M\leqslant 100\right )$,$T$代表总共能够用来采药的时间,$M$代表山洞里的草药的数目。接下来的$M$行每行包括两个在$1$到$100$之间(包括$1$和$100$)的的整数,分别表示采摘某株草药的时间和这株草药的价值。

输出格式

输出在规定的时间内可以采到的草药的最大总价值。

样例数据

输入

70 3
71 100
69 1
1 2

输出

3

分析

用$Dp$数据确定采与不采这两种状态,如果采,那么此时的价值为$Dp_{j-Time_{i}}+Value_{i}$,如果不采,那么价值为$Dp_{j}$,取采与不采的最大值,最后$Dp_{T}$表示总价值

代码

#include <bits/stdc++.h>

#define Enter puts("")
#define Space putchar(' ')

using namespace std;

typedef long long ll;
typedef double Db;

inline ll Read()
{
    ll Ans = 0;
    char Ch = getchar() , Las = ' ';
    while(!isdigit(Ch))
    {
        Las = Ch;
        Ch = getchar();
    }
    while(isdigit(Ch))
    {
        Ans = (Ans << 3) + (Ans << 1) + Ch - '0';
        Ch = getchar();
    }
    if(Las == '-')
        Ans = -Ans;
    return Ans;
}

inline void Write(ll x)
{
    if(x < 0)
    {
        x = -x;
        putchar('-');
    }
    if(x >= 10)
        Write(x / 10);
    putchar(x % 10 + '0');
}

int T , M;
int Time[100001] , Value[100001];
int Dp[100001];

int main()
{
    T = Read();
    M = Read();
    for(int i = 1; i <= M; i++)
    {
        Time[i] = Read();
        Value[i] = Read();
    }
    for(int i = 1; i <= M; i++)
        for(int j = T; j >= Time[i]; j--)
            Dp[j] = max(Dp[j] , Dp[j - Time[i]] + Value[i]);
    Write(Dp[T]);
    return 0;
}

 

posted @ 2021-04-27 20:05  Tenderfoot  阅读(107)  评论(0编辑  收藏  举报