给定一个升序的序列,然后将其分为k组连续子序列。求 k组{max(i)-min(i)}的最小和 (i代表被分割的第i组)
思路:这道题 我们先试着枚举分析 例如 1 8 9 10 分为 两组 就会发现 1 | 8 9 10 (10-8+1-1 )==(10-1-(8-1)), 1 8 |9 10 (10-9+8-1)==(10-1 -(9-8)) 每次分割的地方实际上就是没有被减到的地方(相邻的两个数) 所以我们求出先求出相邻的sub然后排序,最后来减去分组个数相同次数的(sub[i])就完成了
总结:对于一些简单问题,不一定涉及复杂算法,但是要找到规律(这也算是半个贪心吧)
完整代码:
#include <iostream> #include <algorithm> using namespace std; const int maxn = 3e5+9; int n,k; int arr[maxn]; int sub[maxn]; bool cmp(int a,int b){ return a>b; } int main(){ ios::sync_with_stdio(false); cin.tie(0); while(cin>>n>>k){ arr[0] = 0; long long int sum = 0; for(int i=0;i<n;i++){ cin>>arr[i]; //第i位与其前一位的差值 if(i>0){ sub[i-1] = arr[i] - arr[i-1]; sum+=sub[i-1]; } } if(n==k) cout<<0<<endl; else{ sort(sub,sub+n,cmp); for(int i=0;i<(k-1);i++){ sum -= sub[i]; } cout<<sum<<endl; } } }