动规之区间动规小结

区间动规主要有两种方法:

一、是先想出递归式,然后将之转化为滚动数组。

二、或者从小区间贪到大区间。

POJ  1159  点击打开链接

AC代码如下:

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
char a[5005];
short dp[5005][5005];
int min(int a,int b)
{
    return a<b?a:b;
}

int main()
{
    int n;
    int ans;
    int i,j;
    while(cin>>n)
    {
        memset(dp,0,sizeof dp);
        cin>>a+1;
        //cout<<a+1;
        for(i=1;i<=n;i++)
        {
            dp[i][i]=0;
        }
        int len;
        for(len=2;len<=n;len++)
        {
            for(i=1;i<=n-len+1;i++)
            {
                j=i+len-1;
                if(a[i]==a[j])
                    dp[i][j]=dp[i+1][j-1];
                else
                {
                    dp[i][j]=min(dp[i][j-1],dp[i+1][j])+1;
                }

            }
        }
        cout<<dp[1][n]<<endl;
    }
    return 0;
}

POJ  2955   点击打开链接

AC代码如下:

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;

int dp[105][105];
char str[1005];

int main()
{
    int i,j,o,t;
    while(cin>>str,str[0]!='e')
    {
        int l=strlen (str);
        for(i=0;i<l;i++)
            for(j=0;j<l;j++)
            dp[i][j]=0;
        for(o=2;o<=l;o++)
        {
            for(i=0;i<l-o+1;i++)
            {
                j=i+o-1;
                for(t=i;t<j;t++)
                {
                    dp[i][j]=max(dp[i][j],dp[i][t]+dp[t+1][j]);
                    if((str[i]=='('&&str[j]==')')||(str[i]=='['&&str[j]==']'))
                        dp[i][j]=max(dp[i][j],dp[i+1][j-1]+2);
                }
            }
        }
        cout<<dp[0][l-1]<<endl;
    }
    return 0;
}

POJ  1141  点击打开链接

AC代码如下:

#include<iostream>
#include<cstring>
using namespace std;

int dp[205][205];
int dd[205][205];
char str[1005];
int l,minn;
int i,j,t,x;

void PRINTF(int s,int e)
{
    if(s>e)
    return ;
    else
    {
        if(s==e)
        {
            if(str[s]=='('||str[s]==')')
                cout<<"()";
            else cout<<"[]";
        }
        else{
                if(dd[s][e]>=0)
                {
                    PRINTF(s,dd[s][e]);
                    PRINTF(dd[s][e]+1,e);
                }
                else
                {
                    cout<<str[s];
                    PRINTF(s+1,e-1);
                    cout<<str[e];
                }
        }
    }
}

void DP()
{
    for(i=0;i<l;i++)
        dp[i][i]=1;
    memset(dd,0,sizeof dd);
    dd[0][0]=-1;
    for(x=2;x<=l;x++)
    {
        for(i=0;i<l-x+1;i++)
        {
            j=i+x-1;
            dd[i][j]=i;
            minn=dp[i][i]+dp[i+1][j];
            for(t=i+1;t<j;t++)
            {
                if(dp[i][t]+dp[t+1][j]<minn)
                {
                    minn=dp[i][t]+dp[t+1][j];
                    dd[i][j]=t;
                }
            }
            dp[i][j]=minn;
            if((str[i]=='('&&str[j]==')')||(str[i]=='['&&str[j]==']'))
                if(minn>dp[i+1][j-1])
                {
                    dp[i][j]=dp[i+1][j-1];
                    dd[i][j]=-1;
                }
        }
    }
    //cout<<dp[0][l-1]<<endl;
}

int main()
{
    cin>>str;
    l=strlen (str);
    DP();
    PRINTF(0,l-1);
    cout<<endl;
    return 0;
}

动规之区间动规小结

时间: 2025-01-02 08:19:25

动规之区间动规小结的相关文章

区间动规平行四边形优化

平行四边形优化,是一种在一类区间动规中减少时间复杂度的方法. 有方程:m(i,j)=min(m(i,k)+m(k+1,j)+w(i,j)),s(i,j)为最优点取到值. 公式:如果有w(i, j)+w(i′, j′)≤w(i′, j)+w(i, j′) 那么我们称函数 w 满足四边形不等式. 就有s(i, j)≤s(i, j + 1)≤s(i + 1, j + 1) 证明思路如下: 我们先要证明:m(i,j)+m(i′,j′)≤m(i′,j)+m(i,j′),i≤i′< j≤ j′ . 分部证明

任性动图--傻瓜式创作动图、创作动图就是这么简单、就是这么任性!!!

作者:www.gudianxiaoshuo.com 傻瓜式创作动图.创作动图就是这么简单.就是这么任性!!! 任性动图能做什么? 1  文字.诗词生成动图 任性横竖写文字 任性设置运动和时间 2 照片添加文字.生成动图 拖入背景照片,便可编辑生成动图 也可多张照片合成动图 3 动图修改.添加文字 拖入动图背景,对其编辑修改 4 出屏动图制作 使用出屏条功能,更容易将原有动图创作为出屏动图 5 微博动图 有时动图的尺寸过大,发到微博上 是不动的 任性动图也支持将大图生成可在微博运动小动图 由任性动

[bzoj1068]压缩[区间动规]

看了lujiaxin的blog,感觉自己好浪啊....好难过 刷题的时候不够投入,每种算法都是只写一两道就过去了,这样怎么可能进步嘛 不要总是抱怨时间太少了 都是自己不努力>_< 好啦 看题 n<=50的范围,记忆化...N^3 f[a][b][t]表示a~b这段区间内,有没有M的最短答案. 枚举断点(很重要的思想),当T==1,显然左边右边都dp一下:(think clearly) 然后,看看左边能不能被压缩,这一句很重要,因为如果区间内没有M的话,它只能是最左边复制呀复制,所以可以保

十准二新老动所按养十规

打开地图显示的名称是龙域 当我将毒牙放在鉴定桌上的时候那中级鉴定师立刻微微惊诧随即道鉴定费金币 大步上前抬头一个冰风刺解决掉一名级弓箭手另外的几个弓箭手立刻吓得面无人色道这个人的攻击太变态了谁能挡住他魔法师魔法师用火球术齐射 成功了我惊喜交加十分钟的时间已经足够我做很多事情了当我将的属性共享在队伍里的时候凌月不由得神色一凛道大家小心点了这个的攻击力好高 扯窃耐沦脊辆俸彰圆尤谫缘http://p.baidu.com/ihome/center?uid=314c6162633632373230333d

洛谷P1063 能量项链 区间动归

题目描述 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的两颗珠子,前一颗珠子的尾标记一定等于后一颗珠子的头标记.因为只有这样,通过吸盘(吸盘是Mars人吸收能量的一种器官)的作用,这两颗珠子才能聚合成一颗珠子,同时释放出可以被吸盘吸收的能量.如果前一颗能量珠的头标记为m,尾标记为r,后一颗能量珠的头标记为r,尾标记为n,则聚合后释放的能量为m*r*n(Mars单位),新产生的珠子的头标

区间动归

石子合并 链接 分析:dp[i][j]表示从i顺时针数j个位置的最大值,规划方向是顺推,初始时dp[i][i]=0.显然,我们需要求出合并个数为2,3,,,,n的情况,对于dp[i][j]我们假设最后一次合并位置为k,dp[i][j]=dp[i][k]+dp[k+1][j]+sum[i,j],因为sum[i,j]表示i到j这段和,跟k取的位置无关,由此可以得到dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]),最大值同理 1 #i

BZOJ1652 [Usaco2006 Feb]Treats for the Cows 区间动归

约翰经常给产奶量高的奶牛发特殊津贴,于是很快奶牛们拥有了大笔不知该怎么花的钱.为此,约翰购置了N(1≤N≤2000)份美味的零食来卖给奶牛们.每天约翰售出一份零食.当然约翰希望这些零食全部售出后能得到最大的收益.这些零食有以下这些有趣的特性: ?零食按照1..N编号,它们被排成一列放在一个很长的盒子里.盒子的两端都有开口,约翰每 天可以从盒子的任一端取出最外面的一个. ?与美酒与好吃的奶酪相似,这些零食储存得越久就越好吃.当然,这样约翰就可以把它们卖出更高的价钱. ?每份零食的初始价值不一定相同

洛谷P1018 乘积最大 区间动归

题目描述 今年是国际数学联盟确定的"2000――世界数学年",又恰逢我国著名数学家华罗庚先生诞辰90周年.在华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学智力竞赛的活动,你的一个好朋友XZ也有幸得以参加.活动中,主持人给所有参加活动的选手出了这样一道题目: 设有一个长度为N的数字串,要求选手使用K个乘号将它分成K+1个部分,找出一种分法,使得这K+1个部分的乘积能够为最大. 同时,为了帮助选手能够正确理解题意,主持人还举了如下的一个例子: 有一个数字串:312, 当N=3,K=1时

【动漫】国产动漫的那些女神级的人物

这和[盘点]中国动漫中的那些男神, 是姊妹贴 以下排名不分前后 我的目标是精华帖http://weibo.com/2015.09.09/p/1001603885028303050110http://weibo.com/2015.09.09/p/1001603885028307244420http://weibo.com/2015.09.09/p/1001603885028311440127http://weibo.com/2015.09.09/p/1001603885028391132405ht