【cf1315E】E。ダブル撤廃(DP)

ポータル

問題の意味:
前に\(2 ^ nは、n個\ 17 \ 1当量) 競技開始\(2 \ CDOT I、2 \ CDOT I-1 \) 2競合と一致します。
ゲームのルール:人はそう直接2回負けた場合、上側ブラケットに入りますすべてのレースに勝つためには、敗者は、下部ブラケットを入力します。勝者ブラケット決勝と敗者のブラケットの最後の勝利に人々を勝つために、最終的に従事した場合にのみ、たった一人になります。
今あなたが持っている\(K \)あなたの好きなチームをサポートしていますが、あなたはそれぞれのゲームの結果を手配することができ、あなたは多くのゲームがあなたの好きなチームを含めると見たいです。
ゲームまでの数はどのくらいを依頼します。
次の図は、これを理解するために組み合わせることができます。

アイデア:
このタイトルは、一目見ただけで考えるのは非常に良いではありません、問題解決に直接見て...その後のアイデアについて話:

  • 総ので\(2 ^ N \)個体、タイトルは、2つをマージと併せて考慮されることが意図されている\(2 ^ {I-1 } \) の\(2 ^ I \)
  • あなたが考える場合は、\(DP \)には、問題をどのように定義\(DP \)ステータスとマージ状態。
  • 最も明白なアイデアはにある(dp_ {I、J、\ \ K}) の長さを表します\(2 ^ I \) のための開始点\(J \) チームの最後に残りのあなたの好きなチームかどうか。しかし、この状態の定義は人を失うことを考えることはできません。2つのマージが、勝利との戦い、そして最終的には最終的には人に頼ることを決定して失う失う戦いを、勝つためではないときにのみので。
  • アカウントの人々が負けに上記の状態で取ることはありませんので、我々は再定義:\(dp_ {I、J、F_1、F_2} \)の長さを表す\(2 ^ I \)のための開始点、\(Jを\) 勝利あなたの好きなチームかどうかのチームの最後のグループ、好きなチームのための下部ブラケット最終チームかどうか。
  • だから我々は、アカウントにのみに必要なすべての状況、取ることができること(DP \)\最後に手動列挙ビット、および合計\(8 \)ケースを。
  • 最後の最後の時間、その後、あなただけでは自分自身で判断することができます。

タイトル挑戦は、状態に定義されており、ゲーム内で遭遇したいくつかの例をクリアしたいと思います。
参照は、コードの詳細を示します。

/*
 * 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;
}

おすすめ

転載: www.cnblogs.com/heyuhhh/p/12363999.html