采药 递归(超时) 动规(AC)

 超时的递归,记得递归函数里面的变量名千万不要取用过的,很容易出错

 

/*
有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。 
我会给你一段时间,在这段时间里,你可以采到一些草药。
如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。

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

*/

#include<bits/stdc++.h>
using namespace std;
int T,M,t,m,price;

void dfs(int time,int have,vector<pair<int,int>>v,int i)
{   
    if(time>=0){price=max(price,have);}
    if(time<0||i==M){return ;}
    //if(time<=0){price=max(price,have);return ;}
     
    
     auto it=v[i];
     int cost=it.first;int val=it.second;
    //cout<<time<<" "<<have<<" "<<i<<" "<<cost<<" "<<val<<" "<<endl;
    
    dfs(time,have,v,i+1);//不选第i个药
    
    dfs(time-cost,have+val,v,i+1);//选第i个药
    
    
}

int main()
{
    while(cin>>T>>M)
    {    price=0;
        vector<pair<int,int>>v(M);
        for(int i=0;i<M;i++)
        {    cin>>t>>m;
            v[i]=make_pair(t,m);
        }
     
     
     //状态向量有2个,选和不选,递归
        dfs(T,0,v,0);
     cout<<price<<endl;
        
    }
    
    return 0;
}

 

AC的动规,该步要视前面所有的步来决定,而非仅看前一步

/*
有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。 
我会给你一段时间,在这段时间里,你可以采到一些草药。
如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。

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

*/

#include<bits/stdc++.h>
using namespace std;
int T,M,t,m,price;

int main()
{
    while(cin>>T>>M)
    {    price=0;
        vector<pair<int,int>>v(M);
        for(int i=0;i<M;i++)
        {    cin>>t>>m;
            v[i]=make_pair(t,m);
        }
       vector<int>dp(T+1,0);
         
     int cost=0,val=0;
     
      for(int i=0;i<M;i++)//对每个草药
      {    cost=v[i].first;val=v[i].second;
          for(int j=T;j>=cost;j--)//从后往前判断,在这个草药能取的cost区间取max,如cost=69,那么只能放在69,70
          {
              dp[j]=max(dp[j],dp[j-cost]+val);
          }
      }
     cout<<dp[T]<<endl;
        
    }
    
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值