题目描述
知识点
动态规划之最大连续子序列和
实现
码前思考
- 这道题目我写的时候没有发现可以使用最大连续子序列和去做(我好菜,我好笨😭),所以我的思路是这样的:
代码实现
#include <cstdio>
#include <algorithm>
using namespace std;
//共享数据结构记得初始化
//数组下标从0开始
//是否会超界
const int maxn = 1e5+10;
int n;
int seq[maxn];
//dp[i]表示当前的[0]到[i]的最大前缀和
int dp[maxn];
int sum[maxn];
int main(){
while(scanf("%d",&n)!=EOF){
//l与r可以无
int ans = 0;
for(int i=0;i<n;i++){
scanf("%d",&seq[i]);
ans += seq[i];
sum[i] = ans;
}
//首先进行初始化
dp[0] = (1890*seq[0]+143)%10007;
ans = max(ans,dp[0]+sum[n-1]-sum[0]);
for(int i=1;i<n;i++){
int cur = (seq[i]*1890+143) % 10007;
if(cur+sum[i-1] > cur+dp[i-1]){
dp[i] = cur+sum[i-1];
}else{
dp[i] = cur+dp[i-1];
}
ans = max(ans,dp[i]+sum[n-1]-sum[i]);
}
printf("%d\n",ans);
}
return 0;
}
码后反思
- 看了网上的答案,才发现这道题目其实是最大连续子序列和的变式。
#include <cstdio> #include <algorithm> using namespace std; const int maxn = 1e5+10; int seq[maxn]; int data[maxn]; int dp[maxn]; int n; int sum; int main(){ while(scanf("%d",&n)!=EOF){ sum = 0; for(int i=0;i<n;i++){ scanf("%d",&seq[i]); data[i] = ((1890*seq[i]+143)%10007) - seq[i]; sum += seq[i]; } //进行dp数组的初始化 dp[0] = data[0]; for(int i=1;i<n;i++){ dp[i] = max(data[i],data[i]+dp[i-1]); } //一定要初始化为0。。。 int ans = 0; for(int i=0;i<n;i++){ ans = max(dp[i],ans); } int res = ans+sum; printf("%d\n",res); } return 0; }
这里就是使用了最大连续子序列的一个变式,有一点点的思维量。
需要注意的点有:ans
一定要初始化为0
,不能初始化为dp[0]
,因为要考虑到输入样例中Case 1的那种情况。