【题解】LuoGu5662:纪念品

原题传送门

  • 枚举当前是第几天
  • d p i dp_i dpi表示今天本金是 i i i的情况下,今天买进,明天卖出后会获得最多的利润
  • 就是说,转化了题意,把 p i + 1 , j − p i , j p_{i+1,j}-p_{i,j} pi+1,jpi,j当做一个物品
  • 枚举商品, d p k = m a x ( d p k , d p i − p i , j + p i + 1 , j − p i , j ) ( i 为 第 几 天 , j 为 商 品 , k 为 本 金 ) dp_k=max(dp_k,dp_{i-p_{i,j}}+p_{i+1,j}-p_{i,j})(i为第几天,j为商品,k为本金) dpk=max(dpk,dpipi,j+pi+1,jpi,j)(ijk)
  • 每天更新金币上限, m = m a x ( m , m + d p m ) m=max(m,m+dp_m) m=max(m,m+dpm)

Code:

#include 
#define maxn 10010
using namespace std;
int t, n, m, p[110][110], dp[maxn];

inline int read(){
	int s = 0, w = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
	for (; isdigit(c); c = getchar()) s=  (s << 1) + (s << 3) + (c ^ 48);
	return s * w;
}

int main(){
	t = read(), n = read(), m = read(); 
	for (int i = 1; i <= t; ++i)
		for (int j = 1; j <= n; ++j) p[i][j] = read();
	for (int i = 1; i < t; ++i){
		memset(dp, 0, sizeof(dp));
		for (int j = 1; j <= n; ++j)
			for (int k = p[i][j]; k <= m; ++k) dp[k] = max(dp[k], dp[k - p[i][j]] + p[i + 1][j] - p[i][j]);
		m = max(m, dp[m] + m);
	}
	printf("%d\n", m);
	return 0;
}

你可能感兴趣的:(题解,noip,DP,题解,LuoGu,Dp,NOIp,背包’)