HDU 1024 Max Sum Plus Plus【DP,最大mサブセグメント和】
3462 ワード
タイトルリンク:
http://acm.hdu.edu.cn/showproblem.php?pid=1024
タイトル:
与えられたシーケンス、与えられたm、mサブセグメントの最大和を求める.
分析:
dp[i][j]をj番目の要素で終わるiサブセグメントの和とする.各要素に対して前の要素と一緒に1つのサブセグメントを構成することと,1つのサブセグメントを単独で開くことの2つの可能性について,状態遷移方程式
時間複雑度O(m∗n 2),nは1 e 6に達し,必ずタイムアウトした.次に、スクロール配列を用いて空間と時間の最適化を行うことができる.このdp[i−1][k]は、前のj要素の中性子セグメント数がi−1の最大値である配列を直接開き、ansで現在の数のサブセグメントの最大値を記録し、サブセグメント数が増加する過程で更新される.時間複雑度O(n∗m).ansも配列dpもtもlong longすべきだと思いますが、intもAもできることに気づきました...
コード:
http://acm.hdu.edu.cn/showproblem.php?pid=1024
タイトル:
与えられたシーケンス、与えられたm、mサブセグメントの最大和を求める.
分析:
dp[i][j]をj番目の要素で終わるiサブセグメントの和とする.各要素に対して前の要素と一緒に1つのサブセグメントを構成することと,1つのサブセグメントを単独で開くことの2つの可能性について,状態遷移方程式
dp[i][j] = max(dp[i][j - 1], dp[i - 1][k]) + a[j] (k >= i - 1 && k <= j - 1)
時間複雑度O(m∗n 2),nは1 e 6に達し,必ずタイムアウトした.次に、スクロール配列を用いて空間と時間の最適化を行うことができる.このdp[i−1][k]は、前のj要素の中性子セグメント数がi−1の最大値である配列を直接開き、ansで現在の数のサブセグメントの最大値を記録し、サブセグメント数が増加する過程で更新される.時間複雑度O(n∗m).ansも配列dpもtもlong longすべきだと思いますが、intもAもできることに気づきました...
コード:
#include<cstdio>
#include<cstring>
#include<iostream>>
using namespace std;
#define sa(a) scanf("%d", &a)
#define sal(a) scanf("%I64d", &a)
const int maxn = 1e6 + 5, INF = 0x3f3f3f3f;
int a[maxn];
long long dp[maxn], t[maxn];
int main (void)
{
int n, m;
while(~scanf("%d%d", &m, &n)){
memset(dp, 0, sizeof(dp));
memset(t, 0, sizeof(t));
for(int i = 1; i <= n; i++) sa(a[i]);
long long ans;
for(int i = 1; i <= m; i++){
ans = -INF;
for(int j = i; j <= n; j++){
dp[j] = max(dp[j - 1], t[j - 1])+ a[j];
t[j - 1] = ans;
ans = max(ans, dp[j]);
}
}
printf("%d
", ans);
}
return 0;
}
/* 1 2 2 3 3 3 -3 -3 -3 */