小Q和牛博士在玩一个石子合并的游戏,初始一共有n堆石子,每堆石子有w[i]个石子。小Q和牛博士他们需要对石子堆进行合并,每次他们可以任意选择两堆石子进行合并。一堆有x个石子的石子堆和一堆有y个石子的石子堆合并将得到一堆x+y个石子的石子堆,这次合并得分为x*y,当只剩下一堆石子的时候游戏结束。
、小Q和牛博士希望采取优秀的策略获得最大得分,希望你能来帮他们算算最大得分多少。
小Q和牛博士在玩一个石子合并的游戏,初始一共有n堆石子,每堆石子有w[i]个石子。小Q和牛博士他们需要对石子堆进行合并,每次他们可以任意选择两堆石子进行合并。一堆有x个石子的石子堆和一堆有y个石子的石子堆合并将得到一堆x+y个石子的石子堆,这次合并得分为x*y,当只剩下一堆石子的时候游戏结束。
、小Q和牛博士希望采取优秀的策略获得最大得分,希望你能来帮他们算算最大得分多少。
输入包括两行,第一行一个正整数n(2≤n≤100)。
第二行包括n个正整数w[i](1≤w[i]≤100),即每堆石子的个数。
输出一个正整数,即小Q和牛博士最大得分是多少。
3 1 2 3
11
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Stack;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine().trim());
String[] strStone = br.readLine().trim().split(" ");
int score = 0;
Stack<Integer> stack = new Stack<>();
for(int i = 0; i < n; i++)
stack.push(Integer.parseInt(strStone[i]));
// 直接对栈顶的两堆石子弹出进行合并,合并结果再压入站中,重复这一过程直至栈中只有一堆石子
while(stack.size() > 1){
int num1 = stack.pop();
int num2 = stack.pop();
score += num1*num2;
stack.push(num1 + num2);
}
System.out.println(score);
}
} import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n =sc.nextInt();
int[] arr = new int[n];
for(int i=0;i<n;i++){
arr[i] = sc.nextInt();
}
Arrays.sort(arr);
int sum = 0;
int num = arr[0];
for(int i=1;i<n;i++){
sum = sum+arr[i]*num;
num = num + arr[i];
}
System.out.println(sum);
}
}
#include <bits/stdc++.h>
using namespace std;
int main(){ int n,x,y;
while(cin>>n) {
priority_queue<int, vector<int>, greater<int>> q;
for(int i=0;i<n;i++) {
cin>>x;
q.push(x);
} int s = 0;
while(q.size()>1) {
x = q.top();
q.pop();
y = q.top();
q.pop();
s += x*y;
q.push(x+y);
}
cout<<s<<endl;
}
return 0;
}
#include <iostream>
using namespace std;
int main() {
int n; cin >> n;
int stock = 0, score = 0;
for(int curr; cin >> curr; ) {
score += stock * curr;
stock += curr;
}
cout << score;
} 其实顺序完全不影响的。无论什么顺序都是一样的结果。
设w1,w2,...,wn是一个任意的合并顺序(即先取w1,之后w1和w2合并,再之后w1 + w2,w3合并……)
在该合并顺序下的得分为:
将上面的式子乘以二,再将含有w1,w2,...wn的项提出来(把下面的和上面的对比你会发现每一个都多用了一遍),得到:
记,那么其实总得分就是
,与具体序列的顺序无关,只与序列元素的值有关。
import java.util.*;
public class Main {
private static final int MAX = 105;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] arr = new int[MAX];
for (int i=1; i<=n; i++) {
arr[i] = sc.nextInt();
}
int ans = 0, cur = arr[1];
for (int i=2; i<=n; i++) {
ans += cur * arr[i];
cur += arr[i];
}
System.out.println(ans);
return;
}
}
package main
import (
"fmt"
"sort"
)
func main() {
var n int
fmt.Scan(&n)
arr:=make([]int,n)
for i:=0;i<n;i++{
fmt.Scan(&arr[i])
}
sort.Ints(arr)
ans:=0
for len(arr)>1{
x,y:=arr[len(arr)-2],arr[len(arr)-1]
ans+=x*y
arr=append(arr[:len(arr)-2],x+y)
}
fmt.Print(ans)
} 两两乘积求和就完事了,为毛要排序?
n=int(input())
w=[int(i) for i in raw_input().split(' ')]
s=0
for i in range(n-1):
for j in range(i+1,n):
s+=w[i]*w[j]
print s #include <stdio.h>
#include <stdlib.h>
#define MAXN 101
long long n;
long long a[MAXN];
int cmp(const void* a,const void* b); //´Ó´óµ½Ð¡
int main()
{
long long i,sum=0;
scanf("%lld",&n);
for(i=0;i<n;i++)
scanf("%lld",a+i);
qsort(a,n,sizeof(a[0]),cmp);
for(i=1;i<n;i++)
{
sum += a[i] * a[i-1];
a[i] += a[i-1];
}
printf("%lld\n",sum);
return 0;
}
int cmp(const void* a,const void* b)
{
return *(int *)b - *(int *)a;
} while True:
try:
n=int(input().strip())
inp=list(map(int,input().strip().split(' ')))
#print(inp)
inp=sorted(inp)
list1=[]
while len(inp)!=1:
sum1=inp[-1]+inp[-2]
mul=inp[-1]*inp[-2]
list1.append(mul)
inp=inp[:-2]+[sum1]
#print(list1)
result=sum(list1)
print(result)
except:
break
# 获取输入的数据 n = int(input()) w = list(map(int, input().split())) # 初始化得分为0 score = 0 def cross(w, score): """ 定义一个函数,每次调用都会合并w中最接近的两项 :param w: :param score: :return: """ # if n == 1: # return w, score # 对w的预处理,排序;使得最相近的两数相邻 w = sorted(w) # 求w的极差 gap = max(w)-min(w) # 寻找最相邻的两数也是一个遍历过程,可能的取值从0到极差 for i in range(gap+1): # 从头遍历w中的 每个元素,看它与它的前一项是否符合本轮要找的最相近的两数 for j in range(1, len(w)): if w[j]-w[j-1] == i: # 当找到最相邻的两数时,更新得分 score += w[j]*w[j-1] # w得到两数合并之后的新的成员 w.append(w[j] + w[j - 1]) # 除去旧的成员 w.pop(j) w.pop(j-1) # 只要找到就可以直接推出循环,返回新的w与更新过的score return w, score while True: # 多次调用函数,直到w长度为1时,推出循环 if len(w) == 1: break else: w, score = cross(w, score) print(score)
n=int(input()) L=list(map(int,input().split())) L.sort() s=0 for i in range(n-1): t=L.pop() s+=(t*L[-1]) L[-1]+=t print(s)