1 条题解
-
0
#include<bits/stdc++.h> using namespace std; // [1] n-纪念品的数量;arr数组-存储每个纪念品的初始价格(下标1~n) int n,arr[2100]; // [2] dp[l][r]-区间[l, r]内的纪念品,在剩余天数里卖出能获得的最大收益 int dp[2100][2100]={}; int main(){ // 问题分析:区间DP问题,每天只能卖当前区间最左/最右的纪念品,第C天卖出价格为p_i×C,求N天卖完所有纪念品的最大收益 // 解题步骤:1.初始化单个纪念品的区间(最后一天卖出,价格为p_i×n);2.按区间长度从小到大动态规划,计算每个区间的最大收益; // 3.状态转移:选择卖最左或最右的纪念品,收益为当前卖出价格+剩余区间的最大收益;4.最终dp[1][n]即为整个区间的最大收益 cin>>n; for(int i=1;i<=n;i++) cin>>arr[i]; // [3] 读取每个纪念品的初始价格 // 1. 初始化:长度为1的区间(单个纪念品),会在第n天(最后一天)卖出,价格为arr[i]×n for(int i=1;i<=n;i++) dp[i][i]=arr[i]*n; // [4] 区间[i,i]只有一个纪念品,直接计算最后一天的收益 // 区间DP核心循环:按区间长度从小到大计算(len为区间长度,从2到n) for(int len=2;len<=n;len++){ // 3. k-当前区间对应的卖出天数:总天数n,区间长度为len时,该区间的纪念品会在第k天开始卖(k = n - len + 1) int k=n-len+1; // 遍历所有长度为len的区间的左端点l for(int l=1;l+len-1<=n;l++){ int r=l+len-1; // [5] 计算当前区间的右端点r // 4. 状态转移:选择卖最左或最右的纪念品,取收益较大的情况 // 卖左端点l:收益=arr[l]×k(第k天卖出l) + 剩余区间[l+1, r]的最大收益dp[l+1][r] // 卖右端点r:收益=arr[r]×k(第k天卖出r) + 剩余区间[l, r-1]的最大收益dp[l][r-1] dp[l][r]=max(dp[l+1][r]+arr[l]*k,dp[l][r-1]+arr[r]*k); } } cout<<dp[1][n]; // [6] 输出整个区间[1, n]的最大收益,即卖完所有纪念品的最大收入 return 0; }
- 1
信息
- ID
- 1350
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者