给定1~n,每次可以合并两个数字,得到平均值,求怎么合并能使得最后剩下的数字最大
显然每次选择最小的两个数字合并是最优策略。我们可以对每个数字用一个加权值 ,显然越大的数字这个权值要用越大的加权值,最大的合并一次,用0.5,次大的合并两次用0.25.
这样我们就可以O(n)解决了。其实1~n这些固定数字显然可以化简式子
[
egin{array}{l}
S_{n}&=frac{1}{2^{n}}+frac{2}{2^{n-1}}+cdots+frac{n}{2}(1) \
由等比数列求和公式
S_{n}&=frac{a_1 (1-q^n)}{1-q} =1
\
2 S_{n}&=frac{1}{2^{n-1}}+frac{2}{2^{n-2}}+cdots+n(2) \
ext { (2) }-(1) S_{n}&=n-frac{1}{2^{n}}-frac{1}{2^{n-1}}-cdots-frac{1}{2}=n-1+frac{1}{2^{n}} \
a n s=S_{n}+frac{1}{2^{n}}&=n-1+frac{1}{2^{n-1}}
end{array}
去年我写了个矩阵不知道干什么的。。如果看得懂可否告诉我。
]
#include<bits/stdc++.h>
#define rep(i,j,k) for(register int i(j);i<=k;++i)
#define drp(i,j,k) for(register int i(j);i>=k;--i)
using namespace std;
typedef long long lxl;
inline char gt()
{
// return getchar();
static char buf[1<<21],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;
}
template <typename T>
inline void read(T &x)
{
register char ch = gt();
x = 0;
int w(0);
while(!(ch >= '0' && ch <= '9'))w |= ch == '-', ch = gt();
while(ch >= '0' && ch <= '9')x = x * 10 + (ch & 15), ch = gt();
w ? x = ~(x - 1) : x;
}
template <typename T>
inline void out(T x)
{
if(x < 0) x = -x, putchar('-');
char ch[20];
int num(0);
while(x || !num) ch[++num] = x % 10 + '0', x /= 10;
while(num) putchar(ch[num--]);
putchar('
');
}
const int N = 1e9;
vector<double>v;
int n;
const int mod = 1e9 + 7;
inline lxl qpow(lxl a, int b)
{
lxl r(1);
for(; b; a = a * a % mod, b >>= 1) if(b & 1) r = r * a % mod;
return r;
}
struct matrix
{
lxl a[5][5];
int n, m;
matrix()
{
memset(a, 0, sizeof a);
}
} I, A;
matrix operator *(const matrix &x, const matrix & y )
{
matrix a;
a.n = x.n;
a.m = y.m;
rep(i, 1, x.n)
rep(j, 1, y.m)
rep(k, 1, x.m)
a.a[i][j] = (a.a[i][j] + x.a[i][k] * y.a[k][j] % mod) % mod;
return a;
}
namespace one{
int main(){
cout<<(n-1+qpow(qpow(2,n-1),mod-2) ) %mod;
return 0;
}
}
int main()
{
freopen("nbc.in", "r", stdin);
freopen("nbc.out", "w", stdout);
read(n);
one::main();
return 0;
lxl k = n - 1;
A.n = 1;
A.m = 3;
A.a[1][1] = 1;
A.a[1][2] = 2;
A.a[1][3] = 1;
I.n = I.m = 3;
I.a[1][1] = I.a[2][1] = qpow(2, mod - 2);
I.a[2][2] = I.a[3][2] = I.a[3][3] = 1;
while(k)
{
if(k & 1) A = A * I;
I = I * I;
k >>= 1;
}
out(A.a[1][1] % mod);
return 0;
}