CF888E Maximum Subsequence (折半枚舉+ two-pointers)

來源:互聯網
上載者:User

標籤:sum   題意   pen   mat   typename   algo   ret   bre   思想   

題意

給定一個包含\(n\)個數的序列\(a\),在其中任選若干個數,使得他們的和對\(m\)模數後最大。(\(n\leq 35\))

題解

顯然,\(2^n\)的暴枚是不現實的...,於是我們想到了折半枚舉,分成兩部分暴枚,然後考慮合并,合并的時候用two-pointers思想掃一遍就行了。

其實這是一道折半枚舉+Two-Pointers的很好的練手題

//最近CodeForces有點萎,可能會JudgementError,但已經評測過了,能AC,多交幾次應該可以#include <cstdio>#include <algorithm>using std::max;using std::sort;const int N = 40, K = 19;int n, m, k, ans, totx, toty;long long a[N], x[1 << K], y[1 << K];template <typename T>inline void read(T &x) {    x = 0; char ch = getchar();    while (ch < '0' || ch > '9') ch = getchar();    while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();}void dfsx (int i, long long sum) {    if (i > k) { x[++totx] = sum % m; return ; }    dfsx (i + 1, sum + a[i]);    dfsx (i + 1, sum);}void dfsy (int i, long long sum) {    if (i > n) { y[++toty] = sum % m; return ; }    dfsy (i + 1, sum + a[i]);    dfsy (i + 1, sum);}int main () {    read(n), read(m), k = n >> 1;    for (int i = 1; i <= n; ++i) read(a[i]);    dfsx(1, 0), dfsy(k + 1, 0);    sort(&x[1], &x[totx + 1]), sort(&y[1], &y[toty + 1]);    int l = 1, r = toty;    while (l <= totx) {        while (r && x[l] + y[r] >= m) --r; if(!r) break;        ans = max(ans, int((x[l] + y[r]) % m)), ++l;    }    printf ("%d\n", ans);    return 0;}

CF888E Maximum Subsequence (折半枚舉+ two-pointers)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.