【動態規劃】Problem 4 聰明伶俐的香穗子
阿新 • • 發佈:2018-12-23
Problem 4 聰明伶俐的香穗子
香穗子遇到難題了.
題目是這樣的,一個序列上有n個整數,現在你要取m個,且這m個數的任意兩個不能相隔的太近,否則這樣會太醜,現在問你最大能得到多大的和
輸入:
第一行三個數n,m,k,分別表示n個數,取m個,且m箇中的任意兩個位置差要大於等於K
接下來一行,有n個整數,表示序列上的每個數
輸出:
最大和
Sample Input
4 2 2
3 4 -5 1
Sample Output
5
資料範圍:
n<=10000,m<=100,m<=n
答案保正小於 Maxlongint
這道題真的坑爹……
考試的時候只對了幾組
方程很好想 其實
用F[i][j] 表示前I個數 取j個數的最大值
分兩種情況 取不取第i個數
如果要取 則F[i][j] = F[i - K][j - 1] + A[i]
if not, F[i][j] = F[i - 1][j]
but you know that i must be larger than k…
so...
F[i][j] = F[i - 1][j];
if (i > k)
{
F[i][j] = max(F[i][j], F[i - K][j - 1]);
}
and you know that CPP do not support numbers which are less than zero
so we must move the array
like this
F[i + 10005][j]
as it code is bellow
#include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> using namespace std; int N, M, K; int A[10005]; int F[10005 + 10005][105]; void init_file() { freopen("4.in", "r", stdin); freopen("4.out", "w", stdout); } void read_data() { memset(F, -0x3f, sizeof F); scanf("%d%d%d", &N, &M, &K); for(int i = 1; i <= N; i++) { scanf("%d", &A[i]); if (A[i] > F[i - 1 + 10005][1]) { F[i + 10005][1] = A[i]; } else F[i + 10005][1] = F[i + 10004][1]; } } void work() { for(int i = 1; i <= N; i++) for(int j = 2; j <= M; j++) { F[i + 10005][j] = F[i + 10004][j]; if (i > K) { F[i + 10005][j] = max(F[i + 10005][j], F[i - K + 10005][j - 1] + A[i]); } } printf("%d\n", F[N + 10005][M]); } int main() { init_file(); read_data(); work(); return 0; }