被一道力扣dp题卡了,复健之路太痛苦了
题意
n 个二元组p(i)=(ai,bi) ,求max∑i∈Aai ,有∀i∈A,∀j∈A,bi<bj⇒ai>aj
数据范围
n≤1e3,ai≤1e6,bi≤1e3
分析
一开始按两个不等式来的,写了记忆化搜索,T飞了;尝试剪枝,发现两个不等号维护记忆化搜索太有问题了,看题解是DP,尝试推DP方程。
考虑取二元组p(i) 时,状态可以从何转移来。
这个状态必须满足,每一个二元组要么bj≥bi ,要么aj≤ai 。
如果二元组按a 大到小排序,那么考虑取p(i) 时,j∈[1,i−1] 的二元组p(j) ,只能取bj≥bi ,但如果前面有和ai 相等的,不需要满足b 的条件也可以取,所以我们补充一个b 大到小排序,则条件只剩bj≥bi 一个。
那么DP方程就来了,先将二元组按a 大到小排序,设dp(i) 为考虑前i 个二元组,取到第i 个时的和最大值,有转移方程:
dp(i)=max{dp(j)}+ai,j<i,bj≥bi
这题就这么简单秒杀了…上来就写记忆化搜索的我真是脑抽了…
代码
注:scores就是a,ages就是b
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class Solution { public: int bestTeamScore(vector<int>& scores, vector<int>& ages) { int n=scores.size(); vector<pair<int,int>> p; int dp[1005]; memset(dp,0,sizeof(dp)); for(int i=0;i<n;i++) p.push_back({scores[i],ages[i]}); sort(p.begin(),p.end(),greater<pair<int,int>>()); int ans=0; for(int i=0;i<n;i++) { for(int j=0;j<i;j++) if(p[i].second<=p[j].second) dp[i]=max(dp[i],dp[j]); dp[i]+=p[i].first; ans=max(ans,dp[i]); } return ans; } };
|