20.11.13模擬 挑戰nbc(nbc)
阿新 • • 發佈:2021-10-07
給定1~n,每次可以合併兩個數字,得到平均值,求怎麼合併能使得最後剩下的數字最大
顯然每次選擇最小的兩個數字合併是最優策略。我們可以對每個數字用一個加權值 ,顯然越大的數字這個權值要用越大的加權值,最大的合併一次,用0.5,次大的合併兩次用0.25.
這樣我們就可以O(n)解決了。其實1~n這些固定數字顯然可以化簡式子
#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('\n'); } 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; }
本文來自部落格園,作者:{2519},轉載請註明原文連結:https://www.cnblogs.com/QQ2519/p/15376641.html