Bootstrap

P1048 [NOIP2005 普及组] 采药【C++】

原题链接:https://www.luogu.com.cn/problem/P1048
算法标签:动态规划 01背包
分析过程
一、确定方程状态:dp[i][j]表示的是处理完第 i 株草药,花费时间为 j 的最大总价值
二、建立状态转移方程:dp[i][j] = min( dp[i-1][j], dp[i-1][j-time[i]]+worth[i])
三、考虑初始状态
法一:01背包经典解法

#include<iostream>
#include<algorithm>
using namespace std;
int dp[1009][1009];
int main(){
    int t, m;
    int time[1009], worth[1009];
    cin >> t >> m;
    for( int i=1; i<=m; i++ ){
        cin >> time[i] >> worth[i];
    }
    for( int i=1; i<=m; i++ ){
        for( int j=1; j<=t; j++ ){
        	if(j < time[i]){	// 必须考虑这种情况, 否则wa; 但空间优化可完美解决这个问题
        		dp[i][j] = dp[i-1][j];
        	}else{
        		dp[i][j] = max(dp[i-1][j], dp[i-1][j-time[i]] + worth[i]);
        	}
        }
    }
    cout << dp[m][t];
    return 0;
}

法二:空间优化

#include<iostream>
#include<algorithm>
using namespace std;
int dp[1009];
int main(){
    int t, m;
    int time[1009], worth[1009];
    cin >> t >> m;
    for( int i=1; i<=m; i++ ){
        cin >> time[i] >> worth[i];
    }
    for( int i=1; i<=m; i++ ){
        for( int j=t; j>=time[i]; j-- ){
        	dp[j] = max(dp[j], dp[j-time[i]] + worth[i]);
        }
    }
    cout << dp[t];
    return 0;
}
;