zoukankan      html  css  js  c++  java
  • 【DP专题】——洛谷P5144蜈蚣

    链接:https://www.luogu.org/problem/P5144

    题目背景

    一群人在山上遇见了一条蜈蚣

    题目描述

    在一条山路的转角处,WYH发现了一条有中指一样粗的有N节的蜈蚣。这只蜈蚣马上就吸引了HKE的眼球,HKE深深地爱上了这条魔性的蜈蚣。它的很多对足在前进的时候像波浪一样,颇是有毒。

    但是,热爱解剖动物的MZL却准备把蜈蚣切了。HKE很失落,于是MZL承诺不会完全肢解它,只把它的N节切成M段,每一段包含原蜈蚣完整的一节或多节。

    HKE看到他心爱的蜈蚣会切掉是会觉得恶心的。蜈蚣的每一节都有一个权值W[i],切下来的一段(W[i],W[i+1],...,W[j])带给HKE的恶心值是W[i] xor W[i+1] xor ... xor W[j],这里的xor代表按位异或操作。邪恶的LJC希望HKE受到的总恶心值——也就是每一段子蜈蚣带给HKE的恶心值的和最大,请你求出HKE的最大恶心值。

    (注:按位异或,其运算符号在pascal中为xor,在c++中为^或xor;请注意加法与异或运算的优先级先后顺序)

    输入格式

    第一行,两个整数N,M,表示蜈蚣长N节,切成M段。

    第二行N个整数用空格分开,表示蜈蚣每一节的权值W[1],W[2],...,W[n]。

    输出格式

    一个整数表示最大恶心值。

    一道看起来很简单的dp题。

    首先设计状态:我们知道,如果从1到n顺次来判断,每次读入一段值,看它是加入前面的那段还是独立成新的一段,用f[i][j]表示分到第i组时读到第j段的最大恶心值。

    考虑状态转移:我们假设现在在i与j中有一个位置k,如果把kj这一段做为新的一段的话,那么状态转移就是:

    最后减小复杂度,我们用前缀异或来解决。

    然后dp就行了!

    #include<cstdio>
    #include<iostream>
    using namespace std;
    const int N=1010;
    int n,m;
    int w[N],sum[N];
    int dp[200][N];
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%d",&w[i]);    
            sum[i]=sum[i-1]^w[i];
        } 
        for(int i=1;i<=n;i++) dp[1][i]=sum[i];
        for(int i=2;i<=m;i++){
            for(int j=i;j<=n;j++){
                for(int k=i-1;k<j;k++){
                    dp[i][j]=max(dp[i][j],dp[i-1][k]+(sum[j]^sum[k]));
                }
            }
        }
        printf("%d",dp[m][n]);
        return 0;
    }
    ——抓住了时间,却不会利用的人,终究也逃不过失败的命运。
  • 相关阅读:
    SQL 学习笔记(一)联表查询
    .NET (OleDb) Access 各个版本的连接字符口串
    加油站
    程序员的编程套路
    落单的数
    读《怎样解题》
    使用org-mode写cnblogs博客
    Emacs 25.1 error solved: url-http-create-request: Multibyte text in HTTP request
    二进制表示小数
    快速幂
  • 原文地址:https://www.cnblogs.com/Nelson992770019/p/11252230.html
Copyright © 2011-2022 走看看