zoukankan      html  css  js  c++  java
  • HDU 5900 QSC and Master (区间DP)

     题目链接   http://acm.hdu.edu.cn/showproblem.php?pid=5900

    题意:给出序列$A_{i}.key$和$A_{i}.value$,若当前相邻的两个数$A_{i}.key$和$A_{i+1}.key$的最大公约数大于1,则可以把这两个数消去,同时消去$A_{i}.value$和$A_{i+1}.value$,每次消去得到的分数为$A_{i}$和$A_{i+1}$的value值,问最大可能得分。

    注意:当$A_{i}$和$A_{i+1}被$消去后,$A_{i-1}$和$A_{i+2}$成为了新的相邻的数。若符合条件则可以继续消去。

    思路:很明显是区间DP,但是我比赛中如何也A不了。原因有两个:1.没有注意到位运算的低优先级。2.没有把所有情况考虑清楚。

             设$f[i][j]$为从第$i$个数到第$j$个数所能得到的最大得分,$j-i+1$从2开始依次枚举,最后枚举到$f[1][n]$(考虑DP的无后效性)

             分类讨论即可。先考虑不合并的情况,则$f[i][j]$被$f[i][k]+f[k + 1][j]$依次更新。

              再考虑合并的情况$f[i][j]$可以被$f[i][k] + a[k + 1] + a[k + 2] + f[k +3][j]$更新。

              特殊情况讨论:当$a[i + 1]$到$a[j - 1]$中所有的数都可以被消去,则$a[i]$和$a[j]$作为相邻的数也可以被消去。这种情况的讨论非常重要!!!

          代码送上

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <functional>
     6 
     7 using namespace std;
     8 
     9 #define REP(i,n)        for(int i(0); i <  (n); ++i)
    10 #define rep(i,a,b)        for(int i(a); i <= (b); ++i)
    11 #define dec(i,a,b)        for(int i(a); i >= (b); --i)
    12 #define for_edge(i,x)        for(int i = H[x]; i; i = X[i])
    13 
    14 const int N    =    100000        +    10;
    15 const int M    =    10000        +    10;
    16 const int Q    =    1000        +    10;
    17 const int A    =    30        +    1;
    18 
    19 typedef long long LL;
    20 
    21 LL f[Q][Q];
    22 bool c[Q][Q];
    23 bool ret[Q][Q];
    24 int T;
    25 int n;
    26 LL a[Q], b[Q];
    27 LL gcd(LL a, LL b){ return b == 0 ? a : gcd(b, a % b); }
    28 
    29 
    30 int main(){
    31     scanf("%d", &T);
    32     while (T--){
    33         scanf("%d", &n);
    34         memset(a, 0, sizeof a);
    35         memset(b, 0, sizeof b);
    36         memset(c, false, sizeof c);
    37         memset(ret, false, sizeof ret);
    38         memset(f, 0, sizeof f);
    39         rep(i, 1, n) scanf("%lld", a + i);
    40         rep(i, 1, n) scanf("%lld", b + i);
    41         rep(i, 1, n - 1) rep(j, i + 1, n) if (gcd(a[i], a[j]) != 1) c[i][j] = true;
    42         rep(i, 1, n - 1) if (gcd(a[i], a[i + 1]) > 1) ret[i][i + 1] = true;
    43         for (int len = 4; len <= n; len += 2){
    44             rep(i, 1, n - len + 1){
    45                 int j = i + len - 1;
    46                 bool flag = false;
    47                 if (c[i][i + 1] && ret[i + 2][j]) flag = true;
    48                 if (c[j - 1][j] && ret[i][j - 2]) flag = true;
    49                 if (c[i][j] && ret[i + 1][j - 1]) flag = true;
    50                 for (int k = i + 2; k <= j - 3; k += 2) if (ret[k][k + 1] && ret[i][k - 1] && ret[k + 2][j]){ flag = true; break;}
    51                 if (flag) ret[i][j] = true;
    52             }
    53         }
    54         
    55         rep(i, 1, n - 1) if (c[i][i + 1]) f[i][i + 1] = b[i] + b[i + 1];
    56         rep(i, 1, n - 2) f[i][i + 2] = max(f[i][i + 1], f[i + 1][i + 2]);
    57         rep(len, 4, n){
    58             rep(i, 1, n - len + 1){
    59                 int j = i + len - 1;
    60                 rep(k, i, j) f[i][j] = max(f[i][j], f[i][k] + f[k + 1][j]);
    61                 if (len % 2 == 0){ if (ret[i + 1][j - 1] && c[i][j]) f[i][j] = max(f[i][j], b[i] + b[j] + f[i + 1][j - 1]); }
    62                 f[i][j] = max(f[i][j], f[i + 1][j]);
    63                 f[i][j] = max(f[i][j], f[i][j - 1]);
    64                 if (c[i][i + 1]) f[i][j] = max(f[i][i + 1] + f[i + 2][j], f[i][j]);
    65                 if (c[j - 1][j]) f[i][j] = max(f[j - 1][j] + f[i][j - 2], f[i][j]);
    66                 rep(k, i + 1, j - 2) if (c[k][k + 1]) f[i][j] = max(f[i][j], f[i][k - 1] + f[k][k + 1] + f[k + 2][j]);
    67             }
    68         }
    69         printf("%lld
    ", f[1][n]);
    70         
    71         
    72     }
    73     
    74     
    75     return 0;
    76     
    77 }
  • 相关阅读:
    Building workspace has encountered a proble
    Eclipse异常关闭,IDE Exception Handler has encountered a problem An internal error has occurred
    jsp中写java代码的方法
    如何在jsp里面写java代码
    jsp中在java里面怎么调文本框里面的值?
    Typescript基本认识
    运行flutter run 报错Could not determine the dependencies of task ':app:compileDebugJavaWithJavac'.
    H5+原生webview实现APP的JavascriptBridge的使用
    vue mounted里使用window.onresize报错问题
    关于elmentui 抽屉 el-drawer 的slot插入的内容无法通过ref访问的问题
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/5913957.html
Copyright © 2011-2022 走看看