HUST 1351 Group

Description

There is a sequence of N numbers. Cut them into not more than K groups without changing their order, and each group must consist of at least L numbers. From left to right, the value of the i-th group is the sum of all numbers in the group multiplying i. Give me the minimum sum of all the values.

Input

The first line is a number T indicating the total number of test cases.(T<=20) Then T cases, for each case: First line is three numbers N, K, L which are descripted above.(1<=N<=20000, 1<=L<=200, 1<=K<=100) Then N numbers ranged in [-1000, 1000].

Output

For each case, output the minimum sum in a line.

Sample Input

2
5 3 1
3 -2 -1 -4 5
5 3 2
3 -2 -1 -4 5

Sample Output

-1
1

Hint

To get the best answer you can try: Case 1: (3)(-2 -1 -4 5) or (3)(-2)(-1 -4 5) Case 2: (3 -2)(-1 -4 5)

巧妙的dp,关键在于如何简化掉那个多出来的循环
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<iostream>
#include<algorithm>
#include<bitset>
#include<functional>
using namespace std;
typedef unsigned long long ull;
typedef long long LL;
const int INF = 0x7FFFFFFF;
const int maxn = 2e4 + 10;
const int mod = 1e9 + 7;
int T, n, m, L, f[105][maxn], a[maxn], ans;

int main()
{
	cin >> T;
	while (T--)
	{
		scanf("%d%d%d", &n, &m, &L);
		f[1][0] = 0;
		for (int i = 1; i <= n; i++) scanf("%d", &a[i]), f[1][i] = f[1][i - 1] + a[i];
		ans = f[1][n];
		for (int i = 2; i <= m; i++)
		{
			int now = f[i - 1][(i - 1)*L] - i*f[1][(i - 1)*L];
			for (int j = i * L; j <= n; j++)
			{
				f[i][j] = now + i*f[1][j];
				now = min(now, f[i - 1][j - L + 1] - i*f[1][j - L + 1]);
			}
			if (i*L <= n) ans = min(ans, f[i][n]);
		}
		printf("%d\n", ans);
	}
	return 0;
}


你可能感兴趣的:(HUST 1351 Group)