• hdu_5900_QSC and Master(区间DP)


    题目链接:hdu_5900_QSC and Master

    题意:

    有n个数,每个数有个key值,有个val,如果相邻的两个数的key的gcd大于1那么就可以得到这两个数的val的和,现在问怎么取使得到的和最大

    注意:1 2 2 4,第2个和第3个取掉后,第一个就和第4个相邻了

    题解:

    这是一道区间DP题,之前没做过,比赛时没有想出怎么来DP

    考虑区间dp[i][j],枚举i到j的k,然后更新一下当前的最大值

    如果gcd(i,j)>1,如果i+1=j,说明是相邻的,直接相加,如果dp[i+1][j-1]=这段的区间val和,那么中间就可以取掉,说明当前的i,j可以相邻然后取掉

    此时dp[i][j]=max(dp[i][j],dp[i+1][j-1]+val[i]+val[j])

     1 #include<bits/stdc++.h>
     2 #define F(i,a,b) for(int i=a;i<=b;++i)
     3 using namespace std;
     4 typedef long long ll;
     5 
     6 const int N=307;
     7 ll dp[N][N],sum[N];
     8 int T,n,val[N],a[N];
     9 
    10 ll up(ll &a,ll b){if(a<b)a=b;}
    11 
    12 ll DP()
    13 {
    14     memset(dp,0,sizeof(dp));
    15     F(len,1,n)for(int i=1;i+len<=n;i++)
    16     {
    17         int j=i+len;
    18         F(k,i,j-1)up(dp[i][j],dp[i][k]+dp[k+1][j]);
    19         if(__gcd(val[i],val[j])>1)
    20         {
    21             if(i+1==j)dp[i][j]=a[i]+a[j];
    22             else if(dp[i+1][j-1]==sum[j-1]-sum[i])up(dp[i][j],dp[i+1][j-1]+a[i]+a[j]);
    23         }
    24     }
    25     return dp[1][n];
    26 }
    27 
    28 int main(){
    29     scanf("%d",&T);
    30     while(T--)
    31     {
    32         scanf("%d",&n);
    33         F(i,1,n)scanf("%d",val+i);
    34         F(i,1,n)scanf("%lld",sum+i),a[i]=sum[i];
    35         F(i,2,n)sum[i]+=sum[i-1];
    36         printf("%lld
    ",DP());
    37     }
    38     return 0;
    39 }
    View Code
  • 相关阅读:
    VUE 多页面配置(二)
    VUE 多页面配置(一)
    VUE (vue-cli)脚手架项目说明
    CSS 三角形与圆形
    协同过滤算法之组合加权评分
    用户投票算法
    Android开发学习总结(一)——搭建最新版本的Android开发环境
    关于统计变换(CT/MCT/RMCT)算法的学习和实现
    SIFT 特征提取算法总结
    Android Listener侦听的N种写法
  • 原文地址:https://www.cnblogs.com/bin-gege/p/5901561.html
Copyright © 2020-2023  润新知