codeforces 571B Minimization(dp)
来源:互联网 发布:张艺兴极限挑战知乎 编辑:程序博客网 时间:2024/05/05 16:28
You've got array A, consisting of n integers and a positive integer k. Array A is indexed by integers from 1 to n.
You need to permute the array elements so that value
The first line contains two integers n, k (2 ≤ n ≤ 3·105, 1 ≤ k ≤ min(5000, n - 1)).
The second line contains n integers A[1], A[2], ..., A[n] ( - 109 ≤ A[i] ≤ 109), separate by spaces — elements of the array A.
Print the minimum possible value of the sum described in the statement.
3 21 2 4
1
5 23 -5 3 -5 3
0
6 34 3 4 3 2 5
3
In the first test one of the optimal permutations is 1 4 2.
In the second test the initial order is optimal.
In the third test one of the optimal permutations is 2 3 4 4 3 5.
题目链接http://codeforces.com/contest/572/problem/D
计算|arr[1]-arr[k+1]|+|arr[2]-arr[k+2]|+......+|arr[n-k]-arr[n]|,不妨将前式转换为
|arr[1]-arr[k+1]|+|arr[k+1]-arr[k+1+k]|+|arr[k+1+k]-arr[k+1+k+k]|+.....(其中k+1+k+...+k<=数组元素的个数n)
+|arr[2]-arr[k+2]|+|arr[k+2]-arr[k+2+k]|+|arr[k+2+k]-arr[k+2+k+k]|+....(其中k+2+k+...+k<=数组元素的个数n)
+......
+|arr[k]-arr[k+k]|+|arr[k+k]-arr[k+k+k]|+|arr[k+k+k]-arr[k+k+k+k]|+....(其中k+k+k+...+k<=数组元素的个数n)
这样分成了以1,2....k开头的k组;每组的长度可能是n/k或者n/k+1;
长度为n/k+1的组数为n%k;长度为n/k的组数为k-n%k;
只有每组的元素都是有序的,每组的相邻元素的差的和才会最小;
若每组元素都是有序的,则上面k组的结果就分别等价于:
|arr[1]-arr[k+1+k+.....+k]| ,|arr[2]-arr[k+2+k+...k]| , ....... ,|arr[k]-arr[k+k+k+...k]|;
这样每组的和只与这一组的第一个元素和最后一个元素有关; 类似于((a1-a2)+(a2-a3)+...+(a[n-1]-a[n]))=a1-a[n];
最终结果就是这k组的和;
所以现在的问题就是这k组中n%k个较长的组和k-n%k个较短的组怎么选;
比如第二组数据 -5,-5,3,3,3 ;其中长组的个数为1,短组的个数为1;段组的长度为2;长组的长度为3;
先对数据排序,如果选-5,-5,3为一组(长组),3,3为一组(短组);那么最后结果就是错的;
所以需要递推去分组;
我也是看了别人的程序后才彻底明白的,具体看代码;
#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<map>#include<queue>#include<climits>#include<list>#include<stack>#include<cmath>#define ll long long#define MAX 310000#define mem(a) memset(a,0,sizeof(a))#define mems(a) memset(a,-1,sizeof(a))using namespace std;int arr[MAX];ll dp[5500][5500];int main(){ int n,k; scanf("%d%d",&n,&k); int i; for(i=1;i<=n;++i) { scanf("%d",&arr[i]); } sort(arr+1,arr+n+1); int j; dp[0][0]=0; int num_long,num_short; num_long=n%k;//较长组的个数 num_short=k-num_long;//较短组的个数 int len=n/k;//短组的长度 for(i=0;i<=num_long;++i) { for(j=0;j<=num_short;++j) { if(i==0&&j==0) { continue; } int pos=i*(len+1)+j*len;//当前分了多少个,也是当前所分的组的最后一个元素在arr中的坐标 dp[i][j]=INT_MAX; if(j>0) { dp[i][j]=min(dp[i][j],dp[i][j-1]+arr[pos]-arr[pos-len+1]); } if(i>0) { dp[i][j]=min(dp[i][j],dp[i-1][j]+arr[pos]-arr[pos-len]); } } } printf("%lld\n",dp[num_long][num_short]);}
- codeforces 571B Minimization(dp)
- Codeforces 571B Minimization (DP)
- codeforces 571B B. Minimization(dp)
- codeforces 571B--Minimization(贪心+dp)
- CodeForces 571B Minimization(dp)
- [贪心 + DP] Codeforces #571B. Minimization
- CodeForces 571B Minimization(dp)
- Minimization - Codeforces 571 B
- codeforces 571 B. Minimization
- Codeforces 571B--Minimization
- 【codeforces 571B】Minimization
- Codeforces 571B Minimization
- codeforces #317B. Minimization dp && greedy
- 571B. Minimization(Codeforces Round #317)
- codeforces 317 B. Minimization
- CF#571 B. Minimization (DP)
- codeforce 571 B Minimization
- Codeforces Round #317 [AimFund Thanks-Round] (Div. 1) B. Minimization 贪心 dp
- twisted15 mail_client
- iOS之集合对象:将NSArray和NSDictionary两个集合对象写到一个文件中
- jqmobi(appframework) 小技巧记录
- Line of Sight - POJ 2074 直线交点
- 初识Duilib界面库
- codeforces 571B Minimization(dp)
- 二叉树
- twisted16 mail_stmp
- atlassian JIRA 插件开发(五) — workflow condition、validator和post functions
- K-Nearest Neighbor algorithm K最邻近结点算法
- Ljava.lang.String; cannot be cast to java.lang.String错误
- Welcome to the world of Java! ^O^ cmd + notepad + HelloWorld
- 好文章
- spring下载