zoukankan      html  css  js  c++  java
  • 【tju】【dp】调整队形

    问题描述

    学校艺术节上,规定合唱队要参加比赛,各个队员的衣服颜色不能很混乱:合唱队员应排成一横排,且衣服颜色必须是左右对称的。
    例如:“红蓝绿蓝红”或“红蓝绿绿蓝红”都是符合的,而“红蓝绿红”或“蓝绿蓝红”就不符合要求。
    合唱队人数自然很多,仅现有的同学就可能会有3000个。老师希望将合唱队调整得符合要求,但想要调整尽量少,减少麻烦。以下任一动作认为是一次调整:
    1、在队伍左或右边加一个人(衣服颜色依要求而定);
    2、在队伍中任两个人中间插入一个人(衣服颜色依要求而定);
    3、剔掉一个人;
    4、让一个人换衣服颜色;
    老师想知道就目前的队形最少的调整次数是多少,请你编一个程序来回答他。
    因为加入合唱队很热门,你可以认为人数是无限的,即随时想加一个人都能找到人。同时衣服颜色也是任意的。

    输入文件

    第一行是一个整数n(1≤n≤3000)。
    第二行是n个整数,从左到右分别表示现有的每个队员衣服的颜色号,都是1到3000的整数。

    输出文件

    一个数,即对于输入队列,要调整得符合要求,最少的调整次数。

    输入样例

    5
    1 2 2 4 3

    输出样例

    2

    思路分析

    上一篇文章是在tyvj上搜题的时候手贱做的…尽管都是合唱队型都是dp但本质却完全不同呀…因为衣服的颜色(可以看作字符)要左右对称,所以类似于一个回文串,问你最少的操作次数使一个字符串成为回文串,类似于这道
    但是这一题的操作多了一个“让一个人换衣服颜色”(增加与删除等效,在多的那边删除就等于在少的那边增加),这使得字符串本身的字符可以改变了,我们不能再用之前的方法来处理了,我们需要把回文串那道题换一种更“dp”的办法来做——写状态转移方程吧。
    用dp[i][j]表示以i为起点长度为j的字符串变成回文串需要的操作次数;
    当j=1时本身就是回文串;
    当j=2时如果c[i]==c[i+1]就是回文串。如果不是,操作次数为1(修改一个/在前后添加一个)成为回文串;
    当j>=3时,考察c[i]与c[i+j-1]是否相等。如果相等就是回文串,决策:①不动 ②去掉首 ③去掉尾,如果不相等,决策:①改变首尾中一个人的颜色 ②去掉首 ③去掉尾

    状态转移方程

    初始化:dp[i][1]=0;
    if(j==2) if(c[i]==c[i+1]) dp[i][j]=0; else dp[i][j]=1;
    if(j>=3) if(c[i]==c[i+j-1]) dp[i][j]=min{dp[i+1][j-1],dp[i+1][j]+1,dp[i][j-1]+1}; else dp[i][j]=min{dp[i+1][j-1],dp[i+1][j],dp[i][j-1]}+1;

  • 相关阅读:
    优酷网的架构学习笔记
    同网关劫持与不同网关劫持实例
    .flv和.swf格式文件flash播放器代码
    让IE6显示透明PNG背景图片
    新手买车的九大原则
    服务器不支持FLV视频播放的原因
    功能强大易用的Web视频播放器——Flowplayer(使用方法及演示)
    一个不错的媒体网页播放器(国外的)
    网页表格中单元格线条及边框的设置
    20多个漂亮的使用jQuery交互的网站设计欣赏
  • 原文地址:https://www.cnblogs.com/leotan0321/p/6081417.html
Copyright © 2011-2022 走看看