1. 程式人生 > >Codeforces Avito Code Challenge 2018 D. Bookshelves

Codeforces Avito Code Challenge 2018 D. Bookshelves

多少 -c esp greedy per str rac ont pla

Codeforces Avito Code Challenge 2018 D. Bookshelves

題目連接:

http://codeforces.com/contest/981/problem/D

Description

Mr Keks is a typical white-collar in Byteland.

He has a bookshelf in his office with some books on it, each book has an integer positive price.

Mr Keks defines the value of a shelf as the sum of books prices on it.

Miraculously, Mr Keks was promoted and now he is moving into a new office.

He learned that in the new office he will have not a single bookshelf, but exactly $k$ bookshelves. He decided that the beauty of the $k$ shelves is the bitwise AND of the values of all the shelves.

He also decided that he won‘t spend time on reordering the books, so he will place several first books on the first shelf, several next books on the next shelf and so on. Of course, he will place at least one book on each shelf. This way he will put all his books on $k$ shelves in such a way that the beauty of the shelves is as large as possible. Compute this maximum possible beauty.

Sample Input

10 4
9 14 28 1 7 13 15 29 2 31

Sample Output

24

題意

有n個數字,將他們分成k組,組內求和,組間求按位與,問結果最大是多少

There are n numbers, devide them into k groups. Sum the numbers of each group, and & them. Output the maximum possible answer.

題解:

按位貪心。假設答案為ans,dp[i][j]表示前i個分成j組能不能構成ans。

Greedy for bigger answer. Assume that ans is the answer, dp[i][j] represent j groups which is made by former i numbers can construct ans or not.

代碼

#include <bits/stdc++.h>

using namespace std;

int n, k;
long long a[100];
long long dp[100][100];
long long sum[100];
long long ans;

long long check(long long num) {
    memset(dp, 0, sizeof dp);
    for (int i = 1; i <= n; i++) {
        if ((sum[i] & num) == num) dp[i][1] = 1;
        for (int j = 1; j < i; j++) {
            if (((sum[i] - sum[j]) & num) != num) continue;
            for (int o = 2; o <= min(k, i); o++) dp[i][o] |= dp[j][o - 1];
        }
    }
    return dp[n][k];
}

int main() {
    cin >> n >> k;
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    for (int i = 1; i <= n; i++)
        sum[i] = sum[i - 1] + a[i];

    for (int p = 63; p >= 0; p--) {
        if (check(ans|(1<<p)))
            ans |= (1 << p) ;
    }

    cout << ans << endl;
}

Codeforces Avito Code Challenge 2018 D. Bookshelves