日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Max Sum Array 贪心(2500)

發(fā)布時間:2025/3/19 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Max Sum Array 贪心(2500) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.


題意 :

  • 給一數(shù)組c=[c1,c2,...,cm]c=[c_1,c_2,...,c_m]c=[c1?,c2?,...,cm?],求構(gòu)造一個長度為n的數(shù)組a=[a1,a2,...,an]a=[a_1,a_2,...,a_n]a=[a1?,a2?,...,an?],使得?i∈[1,m]\forall i \in [1,m]?i[1,m]恰好有cic_ici?iii出現(xiàn)在數(shù)組aaa
  • 定義一個函數(shù)f(a)=∑1≤i<j≤n,ai=ajj?if(a)=\sum_{1 \leq i < j \leq n,a_i=a_j}j-if(a)=1i<jn,ai?=aj??j?i,求出f(a)f(a)f(a)的最大值,并且求出當f(a)f(a)f(a)最大時,aaa的構(gòu)造方案

思路 :

  • 容易想到一個貪心,注意到相同的數(shù)字間的距離越遠,對答案的貢獻越大,于是對數(shù)字大小從大到小來考慮,每次都拿出兩個放到aaa兩邊,這就是構(gòu)造方法
  • 接下來考慮對答案的貢獻以及方案數(shù)的計算
  • 首先考慮對答案的貢獻,設(shè)當前aaa中還有numnumnum個位置沒排,當前排個數(shù)為iii的數(shù),設(shè)有cnt[i]cnt[i]cnt[i]個,根據(jù)剛才的策略,容易得出對iii從大到小考慮。首先就是這cnt[i]cnt[i]cnt[i]個數(shù)依次放到數(shù)組兩邊,那么每個數(shù)字的貢獻就是num?cnt[i]?2+cnt[i]num-cnt[i]*2+cnt[i]num?cnt[i]?2+cnt[i]一共有cnt[i]cnt[i]cnt[i]個數(shù)字,乘起來,最后還要算上兩邊對中間的(i?2)?cnt[i](i-2)*cnt[i](i?2)?cnt[i]個數(shù)的貢獻(i?2)?cnt[i]?(num?cnt[i]?2+cnt[i])(i-2)*cnt[i]*(num-cnt[i]*2+cnt[i])(i?2)?cnt[i]?(num?cnt[i]?2+cnt[i])化簡后就是(num?cnt[i])?cnt[i]?(i?1)(num-cnt[i])*cnt[i]*(i-1)(num?cnt[i])?cnt[i]?(i?1) 每輪放數(shù)字結(jié)束后記得把num?=2?cnt[i]num-=2*cnt[i]num?=2?cnt[i],因為有這么多的位置被占了
  • 方案數(shù)的話就很簡單了,對當前個數(shù)為1的時候進行特判,因為這個只能放一邊,其他的都是可以兩邊隨意放,所以就是cnt[i]!cnt[i]!cnt[i]!種,乘法原理即可
#include <iostream> #include <vector>using namespace std; using ll = long long;const int N = 1e6 + 10; const ll MOD = 1e9 + 7;inline void solve() {int n; cin >> n;vector<int> cnt(N);vector<ll> f(N);ll num = 0;for (int i = 1; i <= n; i ++ ){int x; cin >> x;num += x; // num表示一共有多少個位置要放東西cnt[x] ++ ; // cnt數(shù)組表示個數(shù)為x的數(shù)有多少種}f[0] = 1;for (int i = 1; i <= n; i ++ ) f[i] = f[i - 1] * i % MOD; // 計算階乘 f[i] = i!ll res = 0, ways = 1; // 最大值和方案數(shù)for (int i = 1000000; i; i -- ) // 個數(shù) 1000000 -> 1{cnt[i] += cnt[i + 2]; // 注意,之前的數(shù)都只排了兩個,肯定有剩下的,所以需要隔位后綴和if (i == 1) ways = ways * f[cnt[i]] % MOD; // 特判個數(shù)為1的數(shù),如果個數(shù)1(被迫放在同一邊),就是 (cnt[1]!)else ways = ways * f[cnt[i]] % MOD * f[cnt[i]] % MOD; // 否則,是 (cnt[i]!) * (cnt[i]!) (兩邊位置和)res = (res + (num - cnt[i]) * cnt[i] % MOD * (i - 1) % MOD) % MOD;num -= 2 * cnt[i];}cout << res << ' ' << ways << endl; }int main() {cin.tie(nullptr) -> sync_with_stdio(false);// int _; // cin >> _; // while (_ -- )solve(); }

總結(jié)

以上是生活随笔為你收集整理的Max Sum Array 贪心(2500)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。