有n个水桶,第i个水桶里面水的体积为Ai,你可以用1秒时间向一个桶里添加1体积的水。
有q次询问,每次询问一个整数pi,你需要求出使其中pi个桶中水的体积相同所花费的最少时间。 对于一次询问如果有多种方案,则采用使最终pi个桶中水的体积最小的方案。
4,3,[1,2,3,4],[2,2,4]
[1,0,5]
第一次:花费一秒变为 2 2 3 4
第二次:已经存在两个水的体积一样的桶
第三次:花费五秒从2 2 3 4变为4 4 4 4
2≤n≤1041≤q≤5001≤Ai≤1042≤pi≤n
class Solution { public: /** * * @param n int整型 水桶的个数 * @param q int整型 询问的次数 * @param a int整型vector n个水桶中初始水的体积 * @param p int整型vector 每次询问的值 * @return int整型vector */ vector<int> solve(int n, int q, vector<int>& a, vector<int>& p) { vector<int> r; sort(a.begin(), a.end()); for(auto &x: p){ int s = (x-1)*a[x-1], l=x-1; for(int i=0;i<x-1;i++) s -= a[i]; int Min = s; for(int i=x;i<n;i++){ s += (x-1)*(a[i]-a[i-1])-(a[i-1]-a[i-x]); if(s < Min){ Min = s; l = i; } } for(int i=l-x+1;i<l;i++) a[i] = a[l]; r.push_back(Min); } return r; } };
//感谢勤奋小牛牛的语法帮助 package Day1; import java.util.ArrayList; import java.util.Arrays; public class Solution { /** * * @param n int整型 水桶的个数 * @param q int整型 询问的次数 * @param a int整型一维数组 n个水桶中初始水的体积 * @param p int整型一维数组 每次询问的值 * @return int整型一维数组 */ public int[] solve (int n, int q, int[] a, int[] p) { // write code here int m[] = new int[q]; Arrays.sort(a); for (int i = 0; i < p.length; i++) { int a1 = 0; ArrayList<Integer> A = new ArrayList<Integer>(); for (int j = 0; j < a.length; j++) { a1 = a1 + a[j]; A.add(a1); } int best_w = (int) 10E8; int best_j = 0; for (int j = 0; j < a.length-p[i]+1; j++) { int w = a[j+p[i]-1]*(p[i]-1) - (A.get(j+p[i]-2)-A.get(j)+a[j]); if (w < best_w) { best_w = w; best_j = j; } } m[i] = best_w; for (int j = best_j; j < best_j + p[i]; j++) { a[j] = a[best_j + p[i] - 1]; } } return m; } public static void main(String[] args) { int n = 50; int q = 10; int a[] = {278,125,679,818,337,683,245,67,922,43,310,505,254,951,378,733,373,643,170,632,711,766,256,620,570,51,494,907,388,126,580,823,485,693,969,931,209,455,533,414,318,777,862,102,742,257,550,706,492,968}; int p[] = {28,15,19,38,27,13,23,38,11,30}; Solution s = new Solution(); System.out.println(Arrays.toString(s.solve(n, q, a, p))); } }
public class Solution { public int[] solve (int n, int q, int[] a, int[] p) { // 定义一个数组m用于存储每个询问的答案 int[] ans = new int[q]; // 对桶的水量进行排序 Arrays.sort(a); for (int i = 0; i < p.length; i++) { int a1 = 0; ArrayList<Integer> A = new ArrayList<>(); // 计算前缀和数组A,其中A[i]表示前i个桶的水量之和 for (int j = 0; j < a.length; j++) { a1 = a1 + a[j]; //这里没有前导0, A.add(a1); } int best_w = (int) 10E8;//integer.max_value int best_j = 0; // 枚举起始的桶j,计算添加水量使得p[i]个桶中的水量相等所需的最小时间 for (int j = 0; j < a.length-p[i]+1; j++) { //a[j+p[i]-1]*(p[i]-1)就是添加水量所需的时间 // (A.get(j+p[i]-2) - A.get(j) + a[j])表示这些桶中当前已经有多少水了,需要减去这部分水的贡献。 int w = a[j+p[i]-1]*(p[i]-1) - (A.get(j+p[i]-2)-A.get(j)+a[j]); if (w < best_w) { best_w = w; //最小的时间 best_j = j; //最优的起始桶位置 } } // 将当前的p[i]个桶的水量全部设为最大水量 for (int j = best_j; j < best_j + p[i]; j++) { a[j] = a[best_j + p[i] - 1]; } // 将当前询问的答案记录在数组m中 ans[i] = best_w; } return ans; } public static void main(String[] args) { int n = 50; int q = 10; int a[] = {278,125,679,818,337,683,245,67,922,43,310,505,254,951,378,733,373,643,170,632,711,766,256,620,570,51,494,907,388,126,580,823,485,693,969,931,209,455,533,414,318,777,862,102,742,257,550,706,492,968}; int p[] = {28,15,19,38,27,13,23,38,11,30}; Solution s = new Solution(); System.out.println(Arrays.toString(s.solve(n, q, a, p))); } }
class Solution: def solve(self , n , q , a , p ): # write code here ans = [] a.sort() # 获取最小操作区间 def getminop(x): l,r = 0,x - 1 v = 0 for i in range(x): v += a[i] v = x * a[x - 1] - v cost = v for i in range(x,n): cost = cost + (x * a[i] - a[i]) + a[i - x] - x * (a[i - 1]) if cost < v: v = cost l,r = i - x + 1,i return l,r,v for i in range(q): if p[i] == 1: ans.append(0) continue l,r,v = getminop(p[i]) ans.append(v) for i in range(l,r + 1): a[i] = a[r] return ans
class Solution { public: /** * * @param n int整型 水桶的个数 * @param q int整型 询问的次数 * @param a int整型vector n个水桶中初始水的体积 * @param p int整型vector 每次询问的值 * @return int整型vector */ int f(int n, vector<int>& a, int p) { int t = (p - 1) * a[p - 1]; for (int i = 0; i < p - 1; i++) t -= a[i]; int Min = t, I = p - 1; for (int i = p; i < n; i++) { t += (p - 1) * (a[i] - a[i - 1]) - (a[i - 1] - a[i - p]); if (t < Min) { Min = t; I = i; } } for (int i = I - 1; i > I - p; i--) a[i] = a[I]; return Min; } vector<int> solve(int n, int q, vector<int>& a, vector<int>& p) { sort(a.begin(), a.end()); vector<int> b; for (int i = 0; i < q; i++) b.push_back(f(n, a, p[i])); return b; } };
class Solution { public: /** * * @param n int整型 水桶的个数 * @param q int整型 询问的次数 * @param a int整型vector n个水桶中初始水的体积 * @param p int整型vector 每次询问的值 * @return int整型vector */ vector<int> solve(int n, int q, vector<int>& a, vector<int>& p) { // write code here vector<int> res; vector<int> water(a); sort(water.begin(), water.end()); for(int num : p){ int sum = 0, min = 0, j = 0; for(int i = 0; i < num; ++i) sum += water[i]; min = water[num-1] * num - sum; for(int i = 1; i + num <= n; ++i){ sum += water[i+num-1] - water[i-1]; int temp = water[i+num-1] * num - sum; if(temp < min){ j = i; min = temp; } } for(int i = j; i < j + num - 1; ++i) water[i] = water[j+num-1]; res.push_back(min); } return res; } };
public int[] solve (int n, int q, int[] a, int[] p) { // write code here int[] res=new int[q]; Arrays.sort(a); for (int i = 0; i < q; i++) { int[] sumA=new int[n]; sumA[0]=a[0]; for (int x = 1; x < n; x++) { sumA[x]=sumA[x-1]+a[x]; } int time=Integer.MAX_VALUE; int num=Integer.MAX_VALUE; int index=0; for (int j = 0; j <= n-p[i]; j++) { int tempTime=a[j+p[i]-1]*(p[i]-1)-(sumA[j+p[i]-2]-sumA[j]+a[j]); int tempNum=a[j+p[i]-1]*p[i]; if(tempTime==0){ res[i]=0; time=0; break; }else if(tempTime<time){ time=tempTime; num=tempNum; index=j; }else if(tempTime==time&&tempNum<num){ time=tempTime; num=tempNum; index=j; } } if(time!=0){ res[i]=time; for (int k = index; k < index+p[i]; k++) { a[k]=a[index+p[i]-1]; } } } return res; }