E. Pchelyonok and Segments
E题题解来了,这个题好像也不是很难,一个简单地区间dp吧! 链接: https://codeforces.com/contest/1582/problem/E 题意:
给你一个数组,在这个数组中找出不相交的k个区间,第一个区间长度为k,使区间长度递减的同时,区间和递增,区间长度长的在前面,问最大的k是多少(可以从任意点开始为第一个区间)。
所实话翻译真的很难理解,每一个题翻译都会占用很大的时间。
刚看到题解的时候一看用区间dp,有点蒙,脑袋里面忘记区间dp的模样了,于是就在复习了一下区间dp然后看了看题解的代码,才看懂了。
思路奉上
首先我们求长度递减的不知道长度从哪儿开始,我们可以把数组倒过来从1开始,最后到达最后 一个符合条件的哪一个就是K,在取K的最大值就行了。知道了这一点之后,我们就可以根据区间dp来求这个题目了。
dp[i][j] 代表前i个元素中第j个子段。
错付代码奉上
#include <iostream>
#include<bits/stdc++.h>
#include<stdio.h>
using namespace std;
const int maxn=1e5+5;
int arr[maxn],dp[maxn][505];
long long sum[maxn];
int main()
{
ios::sync_with_stdio(false);cin.tie(0);
int t;int n;
cin>>t;
while(t--)
{
cin>>n;
for(int i=n;i>=1;i--)
cin>>arr[i];
for(int i=0;i<=n;i++)
for(int j=0;j<=500;j++)
dp[i][j]=0,dp[i][1]=arr[i];
for(int i=1;i<=n;i++)
sum[i]=sum[i-1]+arr[i];
int num=1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=500&&j<=i;j++)
{
dp[i][j]=max(dp[i][j],dp[i-1][j]);
int s=sum[i]-sum[i-j];
if(s<dp[i-j][j-1])
{
dp[i][j]=max(dp[i][j],s);
num=max(num,j);
}
}
}
cout<<num<<endl;
}
}
到目前为止真的不知道哪儿错了,在测试3wrong了提交了N次,或许这就是大学生的崩溃瞬间,感觉也别人AC的代码一毛一样但是就是AC不了。
各位大佬有知道我只哪儿错的还望告诉我真的是崩溃了,就写上别人的代码吧:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e5+10;
ll dp[maxn][505];
ll sum[maxn], a[maxn];
int main(){
int T;
scanf("%d", &T);
while(T--){
int n;
scanf("%d", &n);
int ans = 1;
for(int i = 1; i <= n; ++i){
scanf("%lld", &a[i]);
for(int j = 0; j <= 500; ++j)dp[i][j] = 0;
}
for(int i = n; i >= 1; --i)
sum[i] = sum[i + 1] + a[i];
dp[n][1] = a[n];
for(int i = n - 1; i >= 1; --i){
dp[i][1] = max(dp[i + 1][1], a[i]);
for(int j = 2; j <= 500 && i + j <= n; ++j){
dp[i][j] = dp[i + 1][j];
if(dp[i+j][j-1]!=0 && sum[i] - sum[i+j] < dp[i+j][j-1]){
dp[i][j] = max(dp[i][j], sum[i] - sum[i+j]);
ans = max(ans, j);
}
}
}
printf("%d\n", ans);
}
return 0;
}
其实本来还想写点别的,但是调试代码花了两个小时。还没成功,所以今天不太适合调代码了。
就这样吧。。。。。
|