【cf1315E】E. Double Elimination(dp)

Portal

The meaning of problems:
the prior \ (2 ^ n, n \ leq 17 \) a contestant starts \ (2 \ cdot i, 2 \ cdot i-1 \) match the two compete.
Rules of the game: to win every race will enter the upper bracket, the loser will enter the lower bracket, if a person lose out twice so directly. The winner bracket final and the loser bracket final will be just one person, only when engaged in a final, to win people to victory.
Now you have \ (k \) Support your favorite team, you can arrange the outcome of each game, you want to see as many games contain your favorite team.
The number of games up to ask how much.
The following diagram can be combined to understand this:

Ideas:
This title is not very good to think at first glance, looked directly to problem solution ... then talk about ideas:

  • Since total \ (2 ^ n \) individuals, are intended to be considered in conjunction with the title merging two \ (2 ^ {i-1 } \) to \ (2 ^ I \) .
  • If you think \ (dp \) , then the problem into how the definition \ (dp \) status and merge state.
  • The most obvious idea is to \ (dp_ {i, j, k} \) represents the length \ (2 ^ i \) , the starting point for the \ (J \) , finally the rest of the team whether your favorite team. But the definition of this state can not be considered to lose a man. Because when the two merge, not only to win the fight with the win, and lose lose fight with, that finally decides ultimately resort to a man.
  • Because of the above state does not take into account people lose, we redefine: \ (dp_ {I, J, F_1, F_2} \) represents the length of \ (2 ^ I \) , starting point for the \ (J \) , wins the team's last group whether your favorite team, whether the lower bracket final team for the favorite team.
  • So that we can take into account all the circumstances, only need to \ (dp \) manual Enumeration bit, and finally a total of \ (8 \) case.
  • The final final time and then you can judge for themselves alone.

The title challenge is defined in the state, and would like to clear some of the cases encountered in the game.
See details Code:

/*
 * Author:  heyuhhh
 * Created Time:  2020/2/25 21:11:41
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '\n'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = (1 << 17) + 5, M = 18;

int n, k;
int dp[M][N][2][2];
bool fan[N];

void run(){
    cin >> n >> k;
    for(int i = 1; i <= k; i++) {
        int x; cin >> x;
        fan[x] = 1;   
    }
    memset(dp, -INF, sizeof(dp));
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= (1 << n); j += (1 << i)) {
            if(i == 1) {
                dp[i][j][fan[j]][fan[j + 1]] = (fan[j] | fan[j + 1]);
                dp[i][j][fan[j + 1]][fan[j]] = (fan[j] | fan[j + 1]);
            } else {
                for(int x1 = 0; x1 < 2; x1++) {
                    for(int y1 = 0; y1 < 2; y1++) {
                        for(int x2 = 0; x2 < 2; x2++) {
                            for(int y2 = 0; y2 < 2; y2++) {
                                int cost = dp[i - 1][j][x1][y1] + dp[i - 1][j + (1 << (i - 1))][x2][y2];
                                if(x1 || x2) ++cost;
                                if(y1 || y2) ++cost;
                                
                                dp[i][j][x1][x2] = max(dp[i][j][x1][x2], cost + (x2 | y1));
                                dp[i][j][x1][x2] = max(dp[i][j][x1][x2], cost + (x2 | y2));
                                
                                dp[i][j][x1][y1] = max(dp[i][j][x1][y1], cost + (x2 | y1));
                                dp[i][j][x1][y2] = max(dp[i][j][x1][y2], cost + (x2 | y2));
                                
                                dp[i][j][x2][x1] = max(dp[i][j][x2][x1], cost + (x1 | y1));
                                dp[i][j][x2][x1] = max(dp[i][j][x2][x1], cost + (x1 | y2));
                                
                                dp[i][j][x2][y1] = max(dp[i][j][x2][y1], cost + (x1 | y1));
                                dp[i][j][x2][y2] = max(dp[i][j][x2][y2], cost + (x1 | y2));
                            }
                        }
                    }
                }
            }
        }   
    }
    int ans = 0;
    for(int i = 0; i < 2; i++) {
        for(int j = 0; j < 2; j++) {
            ans = max(ans, dp[n][1][i][j] + (i | j));
        }   
    }
    cout << ans << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    run();
    return 0;
}

Guess you like

Origin www.cnblogs.com/heyuhhh/p/12363999.html