zoukankan      html  css  js  c++  java
  • ZOJ3164【区间dp】

     题意:
    有n个人,有一种关系叫做8g关系,给出m个关系,给出n个人的阵列
    问你最多能拿走多少人,拿走以后相邻就是相邻了
    思路:
    典型的区间dp;
    dp[i][j] 代表 i-j 最多能去多少人;
    如果第i个人能和第j个人有关系而且中间[i+1,j-1]也能全部取走,那么直接dp[i][j]=dp[i+1][j-1]+2;
    不能的话就枚举一下区间分割点,然后取最大和;

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N=3e2+10;
    const int INF=0x3f3f3f3f;
    
    int n,m;
    int dp[N][N],seq[N];
    int inx[N][N];
    
    
    int main()
    {
        while(~scanf("%d%d",&n,&m))
        {
            int a,b;
    
            memset(inx,0,sizeof(inx));
            for(int i=1; i<=m; i++)
            {
                scanf("%d%d",&a,&b);
                    inx[a][b]=inx[b][a]=1;
            }
    
            for(int i=1;i<=n;i++)
                scanf("%d",&seq[i]);
    
            memset(dp,0,sizeof(dp));
            for(int i=1; i<=n; i++)
                if(inx[seq[i]][seq[i+1]])
                    dp[i][i+1]=2;
    
            for(int i=n-2; i>=1; i--)
            {
                for(int j=i+2; j<=n; j++)
                {
                    if(dp[i+1][j-1]==j-i-1&&inx[seq[i]][seq[j]])
                        dp[i][j]=j-i+1;
                    else
                    {
                        for(int k=i; k<j; k++)
                        {
                            if(dp[i][k]+dp[k+1][j]>dp[i][j])
                                dp[i][j]=dp[i][k]+dp[k+1][j];
                        }
                    }
                }
            }
            printf("%d
    ",dp[1][n]);
        }
        return 0;
    }
    


  • 相关阅读:
    P2351 [SDOI2012]吊灯
    洛谷P1450 [HAOI2008]硬币购物 背包+容斥
    P5110 块速递推-光速幂、斐波那契数列通项
    AT2304 Cleaning
    CSP-S 2020
    CF487E Tourists
    P4334 [COI2007] Policija
    动态逆序对专练
    CF437D The Child and Zoo
    CF1032G Chattering
  • 原文地址:https://www.cnblogs.com/keyboarder-zsq/p/6777472.html
Copyright © 2011-2022 走看看