-
题意:长度为\(n\)的数组,确定一个数\(k\),然后连续选\(k,k-1,...,2,1\)个不相交的区间,并且满足区间\(sum\)和严格递增,问你\(k\)的最大取值。
-
题解:我们从后往前遍历,设\(dp[k][i]\)表示当前位置为\(i\),选择区间长为\(k\)的\([i,n]\)中的最大取值,因为我们要求区间是严格递增的,所以取最大最优,那么如果不选当前这个区间,则:\(dp[k][i]=max(dp[k][i+1],...,dp[k][n-k+1])\),如果选择当前这个区间,我们要先判断一下当前区间和是否小于\(dp[k-1][i+k]\),然后再维护最大值:\(dp[k][i]=max(dp[k][i],sum[i+k-1]-sum[i-1])\).
最后还要注意\(dp\)数组的初始值。卡了我好久(
-
代码:
#include <bits/stdc++.h> #define ll long long #define fi first #define se second #define pb push_back #define me memset #define rep(a,b,c) for(int a=b;a<=c;++a) #define per(a,b,c) for(int a=b;a>=c;--a) const int N = 1e6 + 10; const int mod = 1e9 + 7; const int INF = 0x3f3f3f3f; using namespace std; typedef pair<int,int> PII; typedef pair<ll,ll> PLL; ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;} ll lcm(ll a,ll b) {return a/gcd(a,b)*b;} ll dp[501][100010]; int main() { int _; scanf("%d",&_); while(_--){ int n; scanf("%d",&n); for(int k=1;k<=500;++k){ for(int i=1;i<=n+1;++i){ dp[k][i]=0; } } vector<int> a(n+1); vector<ll> sum(n+1); for(int i=1;i<=n;++i){ scanf("%d",&a[i]); sum[i]=sum[i-1]+a[i]; } for(int i=1;i<=n+1;++i){ dp[0][i]=INF; } for(int i=n;i>=1;--i){ for(int k=1;k<=500;++k){ dp[k][i]=dp[k][i+1]; if(i+k-1<=n && sum[i+k-1]-sum[i-1]<dp[k-1][i+k]){ dp[k][i]=max(dp[k][i],sum[i+k-1]-sum[i-1]); } } } int ans; for(int i=500;i>=1;--i){ if(dp[i][1]){ ans=i; break; } } printf("%d\n",ans); } return 0; }
Codeforces Round #750 (Div. 2) E. Pchelyonok and Segments (dp)
转载
???????????????????????????????????????????? ???????????????????????????????? ???????????? ???????????????? ????????????????
???????????????????????????????? ???????? ????????????????
本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。
上一篇:NO.7 2021/10/27(06:15) [周三]
下一篇:32读入Excel
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
Codeforces Round #798 (Div. 2) - E. ANDfinity
Codeforces Round #798 (Div. 2) E. ANDfinity
c++ 算法 开发语言 i++ #define