题目:
题目描述
数学课上,老师在黑板上写了n个数,然后让大家做一个游戏:
每次擦掉黑板上的两个数,然后在黑板上写下这两个数的乘积加一,直到最后只有一个数。同学们做了几次这个游戏之后,发现最终剩下的数大小不一。同学们十分好奇,但老师说:“如果你们能保证剩下的数比我玩的时候剩下的数要小或者相等,那我就告诉你们原因。”
同学们现在十分想知道原因,你能帮帮他们吗?
输入输出格式
输入格式:
第一行有一个正整数n,代表数字的个数。
下一行有n个正整数a1,a2,……,an,表示老师在黑板上写下的数。
输出格式:
一个数,表示同学们最后应该剩下的数,对109+7取模。
输入输出样例
输入样例#1:
3
2 2 3
输出样例#1:
15
说明
样例解释:先将2和3擦掉,写下7,再将7和2擦掉,写下15。
对于20%的数据,n≤8,ai≤10。
对于40%的数据,n≤8。
对于100%的数据,n≤200,ai≤109。
思路:
之前的错误题解
之前做过这道题,写了个神奇的priority_queue思路,然后发现取模后再放入优先队列会影响相对大小关系。
然后发现排个序就好了。
但是之前的思路是对的:
每次擦掉两个最大的数。
假设有3个数a<b<c,那么
(
a
b
+
1
)
∗
c
+
1
=
a
b
c
+
c
+
1
(ab+1)*c+1=abc+c+1
(ab+1)∗c+1=abc+c+1一定大于
(
b
c
+
1
)
∗
a
+
1
=
a
b
c
+
a
+
1
(bc+1)*a+1=abc+a+1
(bc+1)∗a+1=abc+a+1。
所以先擦最大的好。
代码:
#include<bits/stdc++.h>
using namespace std;
#define maxn 200
#define read(x) scanf("%d",&x)
#define md (((int)1e9)+7)
int n;
int a[maxn+5];
int main() {
read(n);
for(int i=1;i<=n;i++) {
int x;
read(x);
a[i]=x;
}
sort(a+1,a+n+1);
int ans=a[n];
for(int i=n-1;i>=1;i--) {
ans=((long long)ans*a[i]+1)%md;
}
printf("%d",ans);
}