zoukankan      html  css  js  c++  java
  • HDU 5900

    题意:   

      给n件物品,有key和value   

      每次可以把相邻的 GCD(key[i], key[i+1]) != 1 的两件物品,问移除的物品的总value最多是多少   

      key : 1 3 4 2  移除34以后12也相邻了,可以移除

    分析:   

      先预处理出所有GCD[l][r], 意味 l <= i <= r的区域可以全部移除, 用记忆化搜索处理   

      然后 dp[i] 代表到 i 为止可以得到的最大value和   

      if (G[l][r]) dp[r] = max(dp[r], dp[l-1] + sum[r] - sum[l-1] )

      以及用 dp[i] = max(dp[i], dp[i-1]) 向后保留最大值

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 #define LL long long
     6 const int MAXN = 305;
     7 int t, n;
     8 LL dp[MAXN];
     9 LL key[MAXN], v[MAXN], sum[MAXN];
    10 int GCD[MAXN][MAXN];
    11 LL gcd(LL a, LL b)
    12 {
    13     return b == 0 ? a : gcd(b, a%b); 
    14 }
    15 bool check(int l, int r)
    16 {
    17     if (l > r) return 1;
    18     if (GCD[l][r] != -1) return GCD[l][r];
    19     if (l == r) return GCD[l][r] = 0;
    20     if ((r-l)%2 == 0) return GCD[l][r] = 0; 
    21     if (l == r-1) return GCD[l][r] = ( gcd(key[l], key[r]) != 1 );
    22     if (gcd(key[l], key[r]) != 1 && check(l+1, r-1) ) return GCD[l][r] = 1;
    23     for (int i = l+1; i < r-1; i++)
    24     {
    25         if (check(l,i) && check(i+1, r)) return GCD[l][r] = 1;
    26     }
    27     return GCD[l][r] = 0;
    28 }
    29 int main()
    30 {
    31     scanf("%d", &t);
    32     while (t--)
    33     {
    34         scanf("%d", &n);
    35         for (int i = 1; i <= n; i++)
    36             scanf("%lld", &key[i]);
    37         sum[0] = 0;
    38         for (int i = 1; i <= n; i++)
    39             scanf("%lld", &v[i]) , sum[i] = sum[i-1] + v[i];
    40         memset(GCD, -1, sizeof(GCD));
    41         for (int i = 1; i <= n; i++)
    42             for (int j = i; j <= n; j++)
    43                 check(i, j);
    44         memset(dp, 0, sizeof(dp));
    45         for (int i = 1; i <= n; i++)
    46         {
    47             for (int j = 2; j <= i; j += 2)
    48             {
    49                 int l = i - j + 1, r = i;
    50                 if (check(l, r))
    51                     dp[i] = max(dp[i], dp[l-1] + sum[r] - sum[l-1]);
    52             }
    53             dp[i] = max(dp[i], dp[i-1]);
    54         }
    55         printf("%lld
    ", dp[n]);
    56     }
    57 } 
    我自倾杯,君且随意
  • 相关阅读:
    mysql创建和删除表
    性能测试工具curlloader(linux)
    Linux安装与硬盘分区
    linux那点事儿(上)
    Linux文件传输与mysql数据库安装
    性能测试工具curlloader二测试分析
    菜鸟学自动化测试(六)selenium 命令之文字范本匹配
    git/github初级运用自如
    开源自动化测试框架Tellurium
    菜鸟学自动化测试(五)selenium命令之定位页面元素
  • 原文地址:https://www.cnblogs.com/nicetomeetu/p/5907060.html
Copyright © 2011-2022 走看看