您的位置:首页 > 产品设计 > UI/UE

sdut 2169 Sequence 区间dp

2016-05-25 12:39 465 查看


Sequence




Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^



题目描述

Given an integer number sequence A of length N (1<=N<=1000), we define f(i,j)=(A[i]+A[i+1]+...+A[j])^2 (i<=j). Now you can split the sequence into exactly M (1<=M<= N) succesive parts, and the cost of
a part from A[i] to A[j] is f(i,j). The totle cost is the sum of the cost of each part. Please split the sequence with the minimal cost.


输入

At the first of the input comes an integer t indicates the number of cases to follow. Every case starts with a line containing N ans M. The following N lines are A[1], A[2]...A
, respectively. 0<=A[i]<=100
for every 1<=i<=N.


输出

For each testcase, output one line containing an integer number denoting the minimal cost of splitting the sequence into exactly M succesive
parts.


示例输入

1
5 2
1 3 2 4 5



示例输出

117



提示

 


来源

山东省第二届ACM大学生程序设计竞赛

示例程序

把长度为n的序列分为m块使得m块的平方和最大

设dp【i,j】为前i个数分为j段那么dp【i,j】=min(dp【i,j】,dp【k,j-1】+sigma(a【z】*a【z】)k<z<i

ac code

#include <iostream>
#include <algorithm>
#include <cstring>
#define ll long long
#define maxn 1001
using namespace std;
ll sum[maxn];
ll dp[maxn][maxn];
int n,loop,m;
int main(){
ios::sync_with_stdio(false);
cin>>loop;
while(loop--){
cin>>n>>m;
sum[0]=0;
memset(dp,1,sizeof(dp));
for(int i=1;i<=n;++i){
ll t;cin>>t;
sum[i]=sum[i-1]+t;
dp[i][1]=sum[i]*sum[i];
}
for(int len=2;len<=m;len++)///枚举分块
for(int i=len;i+m-len<=n;i++){///前i个分为len块 后面最少留m-len块
for(int k=i-1;k>len;k--){
if((sum[i]-sum[k])*(sum[i]-sum[k])<dp[i][len])
dp[i][len]=min(dp[i][len],dp[k][len-1]+(sum[i]-sum[k])*(sum[i]-sum[k]));
}
}
cout<<dp
[m]<<'\12';
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: