zoukankan      html  css  js  c++  java
  • luogu U41573 War2

    一道NOIP2018模拟的DayT3

    原本没打算做,结果Dukelv秒了(强的过分),就来看看。

    状压dp。令dp[i][j]表示在状态 i ,最后选了第 j 个数是的最大分值。

    所以我们枚举状态 i,在枚举最后一个选的 j,再枚举下一个要选的k,容易得出:

      dp[i | (1 << (k - 1))][k] = max(dp[i | (1 << (k - 1))][k], dp[i][j] + G[j][k] + a[k])

    其中G[j][k]是一个邻接表,表示先选 j,再选k能得到的额外加分。

    别忘了初始化dp[1 << (i - 1)][i] = a[i]。

    然后如果当前状态选了m个,就用这个去更新答案。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<cctype>
     8 #include<vector>
     9 #include<stack>
    10 #include<queue>
    11 using namespace std;
    12 #define enter puts("") 
    13 #define space putchar(' ')
    14 #define Mem(a, x) memset(a, x, sizeof(a))
    15 #define rg register
    16 typedef long long ll;
    17 typedef double db;
    18 const int INF = 0x3f3f3f3f;
    19 const db eps = 1e-8;
    20 const int maxn = 19;
    21 inline ll read()
    22 {
    23     ll ans = 0;
    24     char ch = getchar(), last = ' ';
    25     while(!isdigit(ch)) {last = ch; ch = getchar();}
    26     while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
    27     if(last == '-') ans = -ans;
    28     return ans;
    29 }
    30 inline void write(ll x)
    31 {
    32     if(x < 0) x = -x, putchar('-');
    33     if(x >= 10) write(x / 10);
    34     putchar(x % 10 + '0');
    35 }
    36 void MYFILE()
    37 {
    38 #ifndef mrclr
    39     freopen(".in", "r", stdin);
    40     freopen(".out", "w", stdout);
    41 #endif
    42 }
    43 
    44 int n, m, k, a[maxn];
    45 ll G[maxn][maxn];
    46 ll dp[(1 << maxn) + 5][maxn], ans = 0;
    47 
    48 int main()
    49 {
    50     n = read(); m = read(); k = read();
    51     for(int i = 1; i <= n; ++i) a[i] = read();
    52     for(int i = 1; i <= k; ++i)
    53     {
    54         int x = read(), y = read(), w = read();
    55         G[x][y] += w;
    56     }
    57     for(int i = 1; i <= n; ++i) dp[1 << (i - 1)][i] = a[i];
    58     for(int i = 1; i < (1 << n); ++i)
    59     {
    60         int cnt = 0;
    61         for(int j = 1; j <= n; ++j) if(i & (1 << (j - 1)))
    62         {
    63             cnt++;
    64             for(int k = 1; k <= n; ++k) if(!(i & (1 << (k - 1))))
    65                 dp[i | (1 << (k - 1))][k] = max(dp[i | (1 << (k - 1))][k], dp[i][j] + G[j][k] + a[k]);
    66         }
    67         if(cnt == m)
    68         {
    69             for(int j = 1; j <= n; ++j) if(i & (1 << (j - 1)))
    70                 ans = max(ans, dp[i][j]);
    71         }
    72     }
    73     write(ans); enter;
    74     return 0;
    75 }
    View Code
  • 相关阅读:
    HDU 1828 Picture
    HDU 2656 Counting Game
    HDU 3265 Posters
    Android颜色选择器之案例解析
    实现半透明的popupwindow的源码
    用activity实现半透明的、淡入的menu【原创】
    Android webservice的用法详细讲解
    Android Fragments 详细使用详细介绍
    在Android中扫描wifi热点演示实例教程
    用Dialog创建带箭头的对话框
  • 原文地址:https://www.cnblogs.com/mrclr/p/9748092.html
Copyright © 2011-2022 走看看