对于环形的dp 大多情况都是破环成链 例如 那道宝石手镯的环形 一般来说都是要破环成链的。

或者说 是 两次dp 一次断开 一次强制连接即可。

我想 我应该沉淀下来了这些天写的题都有点虚 要不就是看了书 要不就是点开了题解总是在自己未想出的时候 外物影响到我让我感觉特别没有成就感呢。

这就很不爽了 我觉得是真的不爽 ,算了按照原计划行事(oj刷上520)

这道题目 看起来很简单 我的意思是指 很轻而易举的列出来状态和 状态转移方程 事实上也是如此 。

但是唯一难以处理的是 环形的结构 。。我设状态 因为要知道前面那个到底选了没有所以必须要写两个选或不选的状态。

设 f[i][j][0/1] 表到了第i个小时已经形成j段且第i个小时选 0 不选 1。

f[1][1][0]=0; f[1][0][1]=0;

显然 f[i][j][0]=max(f[i-1][j-1][1],f[i-1][j-1][0]+v[j]); f[i][j][1]=max(f[i][j][0],f[i][j][1]);

对于环形的 上述我们断开dp一次了 此时为了弥补刚才断开的后果我们必须要连接上去。

此时状态必然是 f[1][1][0]=v[1]; 此时我们再进行上述dp 然后强制取答案 f[n][k][0]即可。

此时 B<n因为这道题保证了 那么在从一段数到最后的n一定有一个点会做铺垫。

//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<cstring>
#include<string>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<utility>
#include<set>
#include<bitset>
#include<queue>
#include<stack>
#include<deque>
#include<map>
#include<vector>
#include<ctime>
#define INF 2147483646
#define ll long long
#define R register
#define mod 45989
using namespace std;
char buf[<<],*fs,*ft;
inline char getc()
{
return (fs==ft&&(ft=(fs=buf)+fread(buf,,<<,stdin),fs==ft))?:*fs++;
}
inline ll read()
{
ll x=,f=;char ch=getc();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getc();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getc();}
return x*f;
}
inline void put(ll x)
{
x<?putchar('-'),x=-x:;
ll num=;char ch[];
while(x)ch[++num]=x%+'',x/=;
num==?putchar(''):;
while(num)putchar(ch[num--]);
putchar('\n');return;
}
const ll MAXN=;
ll n,k,ans,u,cnt,minn=INF;
ll v[MAXN];
ll f[][MAXN][];
inline ll min(ll x,ll y){return x>y?y:x;}
inline ll max(ll x,ll y){return x>y?x:y;}
//f[i][j][k] 表 前i个小时 分成了j段 且在第 i的小时休息 0 还是不休息 1
int main()
{
//freopen("1.in","r",stdin);
n=read();k=read();
for(ll i=;i<=n;++i)v[i]=read();
if(n==k){for(ll i=;i<=n;++i)cnt+=v[i],minn=min(minn,v[i]);put(cnt-minn);}
memset(f,0xcf,sizeof(f));
f[u][][]=;f[u][][]=;
for(ll i=;i<=n;++i)
{
u=u^;
for(ll j=;j<=min(i,k);++j)
{
f[u][j][]=-INF;f[u][j][]=-INF;
f[u][j][]=max(f[u^][j][],f[u^][j][]);
if(j->=)f[u][j][]=max(f[u^][j-][],f[u^][j-][]+v[i]);
}
}
ans=max(ans,max(f[u][k][],f[u][k][]));
u=;
memset(f,0xcf,sizeof(f));
f[u][][]=v[];
for(ll i=;i<=n;++i)
{
u=u^;
for(ll j=;j<=min(i,k);++j)
{
f[u][j][]=-INF;f[u][j][]=-INF;
f[u][j][]=max(f[u^][j][],f[u^][j][]);
if(j->=)f[u][j][]=max(f[u^][j-][],f[u^][j-][]+v[i]);
}
}
ans=max(ans,f[u][k][]);
put(ans);
return ;
}

一次断开 一次联合 强制联合 。这样即可消除环形带来的影响。

这样的做法当然还可以 用在创世纪上,当然我是不会的。

这道题的思路就比较简单了 n为le6 显然 也是一个dp类型的题目 瞬间单调队列O(1)寻找决策即可。

至于环形 考虑再续上一段 因为在这一段上两点之间的距离如果大于n/2的话那么此时再续上的一段两点之间的距离就小于了 这样我们就可以直接在这一条链上做了。

然后进行决策转移和决策单调性维护即可。

//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<cstring>
#include<string>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<utility>
#include<set>
#include<bitset>
#include<queue>
#include<stack>
#include<deque>
#include<map>
#include<vector>
#include<ctime>
#define INF 2147483646
#define ll long long
#define R register
using namespace std;
char buf[<<],*fs,*ft;
inline char getc()
{
return (fs==ft&&(ft=(fs=buf)+fread(buf,,<<,stdin),fs==ft))?:*fs++;
}
inline ll read()
{
ll x=,f=;char ch=getc();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getc();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getc();}
return x*f;
}
inline void put(ll x)
{
x<?putchar('-'),x=-x:;
ll num=;char ch[];
while(x)ch[++num]=x%+'',x/=;
num==?putchar(''):;
while(num)putchar(ch[num--]);
putchar('\n');return;
}
const ll MAXN=;
ll maxx,n;
ll a[MAXN],q[MAXN],l,r;
int main()
{
//freopen("1.in","r",stdin);
n=read();l=;r=;
for(ll i=;i<=n;++i)a[i]=read(),a[i+n]=a[i];
for(ll i=;i<=n+n/;++i)
{
while(l<=r&&i-q[l]>n/)++l;
if(l<=r)maxx=max(maxx,a[i]+a[q[l]]+i-q[l]);
while(l<=r&&a[q[r]]-q[r]<a[i]-i)--r;
q[++r]=i;
}
put(maxx);
return ;
}

环形dp的更多相关文章

  1. Gym101889J. Jumping frog(合数分解+环形dp预处理)

    比赛链接:传送门 题目大意: 一只青蛙在长度为N的字符串上跳跃,“R”可以跳上去,“P”不可以跳上去. 字符串是环形的,N-1和0相连. 青蛙的跳跃距离K的取值范围是[1, N-1],选定K之后不可改 ...

  2. Luogu【P1880】石子合并(环形DP)

    先放上luogu的石子合并题目链接 这是一道环形DP题,思想和能量项链很像,在预处理过程中的手法跟乘积最大相像. 用一个m[][]数组来存储石子数量,m[i][j]表示从第 i 堆石子到第 j 堆石子 ...

  3. 区间DP中的环形DP

    vijos1312 链接:www.vijos.org/p/1312 题目分析:经典的环形DP(区间DP) 环形DP,首先解环过程,把数组复制一遍,n个数变成2n个数,从而实现解环 dp[i][j]表示 ...

  4. codevs1085数字游戏(环形DP+划分DP )

    1085 数字游戏  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold     题目描述 Description 丁丁最近沉迷于一个数字游戏之中.这个游戏看似简单, ...

  5. P1880 [NOI1995]石子合并[环形DP]

    题目来源:洛谷 题目描述 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计算出将 ...

  6. $Poj2228$/洛谷$SP283\ Naptime$ 环形$DP$

    Luogu 一定要记得初始化为-inf!!! Description 在某个星球上,一天由N小时构成.我们称0-1点为第一个小时,1-2点为第二个小时,以此类推.在第i个小时睡觉能恢复Ui点体力.在这 ...

  7. FZU - 2204 简单环形dp

    FZU - 2204 简单环形dp 题目链接 n个有标号的球围成一个圈.每个球有两种颜色可以选择黑或白染色.问有多少种方案使得没有出现连续白球7个或连续黑球7个. 输入 第一行有多组数据.第一行T表示 ...

  8. NOIP2009pj道路游戏[环形DP 转移优化 二维信息]

    题目描述 小新正在玩一个简单的电脑游戏. 游戏中有一条环形马路,马路上有 n 个机器人工厂,两个相邻机器人工厂之间由一小段马路连接.小新以某个机器人工厂为起点,按顺时针顺序依次将这 n 个机器人工厂编 ...

  9. 动态规划:区间DP与环形DP

    区间型动态规划的典型例题是石子归并,同时使用记忆化搜索实现区间动归是一种比较容易实现的方式,避免了循环数组实现的时候一些边界的判断 n堆石子排列成一条线,我们可以将相邻的两堆石子进行合并,合并之后需要 ...

随机推荐

  1. [转]The Production Environment at Google

    A brief tour of some of the important components of a Google Datacenter.   A photo of the interior o ...

  2. 一个会学习(观察->活学->求变)的人,在任何领域都能变得强大无比

      开始今天的话题之前,我说个小故事.   很早以前有一部美剧,叫<Hero>.   大概讲的是正反两派都是一群有超能力的人,彼此为了某个巨大的阴谋互相撕逼了十多集.虽然剧情很老套,但是让 ...

  3. 理解 CI 和 CD 之间的区别(翻译)

    博客搬迁至https://blog.wangjiegulu.com RSS订阅:https://blog.wangjiegulu.com/feed.xml 原文链接:https://blog.wang ...

  4. Linux端口转发-rinted工具部署、配置、使用

    编者按: 近期由于公司开启定制项目规划,对于每个项目都会开启一个测试服务器,实施方会用到测试服务器的ssh端口.mysql端口.web端口,为了节省资源(公网IP.服务器资源复用),基于rinted工 ...

  5. nginx环境安装配置fail2ban屏蔽攻击ip

    安装 fail2ban   yum install -y epel-release yum install -y fail2ban 设置 Nginx 的访问日志格式 这个是设置 fail2ban 封禁 ...

  6. docker下创建crontab定时任务失败

    创建过程 基础镜像采用的centos7.2,需要安装一下crontab,在dockerfile中加以下语句就可以了: # crontab jobs RUN yum -y install crontab ...

  7. [转]decorators.xml的用法

    原文地址:https://blog.csdn.net/laozhuxiao/article/details/54342121 简介: sitemesh应用Decorator模式,用filter截取re ...

  8. ant 通配符

    ant 通配符 我们常用的匹配模式有ANT模式,比如acegi可以用PATTERN_TYPE_APACHE_ANT来使用ANT匹配模式,那什么是ANT匹配模式呢.   ANT通配符有三种:     通 ...

  9. Failed to execute 'write' on 'Document'动态载入的js不能执行write

    统计代码一般都是直接一个标签,插入js,标签放在哪里,统计图表就放在哪里! 我现在是稍微改了一下,我自己加了一点js,在页面所有元素都加载完成之后我再动态的把统计js插入到我需要的地方. 统计代码的s ...

  10. C# 3个延时函数

    ) { int time = Environment.TickCount; while (true) { if (Environment.TickCount - time >= DelayTim ...