C. Hard problem

这个题目一开始看还感觉比较复杂,但是还是可以写,因为这个决策很简单就是对于这个字符串倒置还是不倒置。

然后我不会一维去转移,直接用二维,第二维用01来表示转移和不转移,这样子就很清楚了。

#include <cstdio>
#include <cstdlib>
#include <map>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#include <string>
#include <iostream>
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 1e5 + ;
const int mod = 1e9 + ;
string s[maxn];
ll dp[maxn][];
ll c[maxn]; int main()
{
int n;
scanf("%d", &n);
for (int i = ; i <= n; i++) scanf("%lld", &c[i]);
for (int i = ; i <= n; i++) cin >> s[i];
dp[][] = c[], dp[][] = ;
for(int i=;i<=n;i++) dp[i][] = dp[i][] = inf;
for(int i=;i<=n;i++)
{
string a = s[i - ];
string b = s[i]; int x = a.compare(b);
//printf("1 x=%d\n", x);
if (x <= ) dp[i][] = min(dp[i - ][], dp[i][]);
reverse(a.begin(), a.end());
x = a.compare(b);
//printf("2 x=%d\n", x);
if (x <= ) dp[i][] = min(dp[i - ][], dp[i][]);
reverse(b.begin(), b.end()); x = s[i - ].compare(b);
//printf("3 x=%d\n", x);
if (x <= ) dp[i][] = min(dp[i - ][], dp[i][]);
x = a.compare(b);
//printf("4 x=%d\n", x);
if (x <= ) dp[i][] = min(dp[i][], dp[i - ][]);
dp[i][] += c[i];
}
if(min(dp[n][],dp[n][])<inf) printf("%lld\n", min(dp[n][], dp[n][]));
else printf("-1\n");
return ;
}

C

C. Another Problem on Strings

这个题目不太像dp,一开始其实没什么思路,后来问题lj,知道思路,但是不知道怎么处理,最后还是上网查了题解

这个题目网上是用 前缀和+二分查找 来处理的

就是前缀和来记录一段区间1的数量,然后再用二分找到我需要的一段区间往前推最早的1的位置,

然后我们往后推移每一个数字,每一次出现的0都是都会再计算一次前面的那个数字。

其实还是有一点点感觉和自己想的不太一样,这个lower_bound 和 upper_bound 只能算到当前值,不然会出问题,

不过应该只会在k==0这种情况下才会出问题吧。

计数:这个题目计数方法很有意思,就是每次找到一个满足条件的区间,求出这个区间长度,然后这个区间往后推移,如果后面的不破坏这个条件,那么就可以继续++

#include <cstdio>
#include <cstdlib>
#include <map>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#include <string>
#include <iostream>
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 1e6 + ;
const int mod = 1e9 + ;
ll sum[maxn];
char s[maxn]; int main()
{
int k;
scanf("%d", &k);
scanf("%s", s + );
int len = strlen(s + );
for(int i=;i<=len;i++)
{
sum[i] = sum[i - ];
if (s[i] == '') sum[i] += ;
printf("sum[%d]=%d\n", i, sum[i]);
}
ll ans = ;
for(int i=;i<=len;i++)
{
if(sum[i]>=k)
{
ll st = lower_bound(sum, sum + i, sum[i] - k) - sum;
ll ed = upper_bound(sum, sum + i, sum[i] - k) - sum;
// printf("ed=%lld st=%lld\n", ed, st);
ans += ed - st;
// printf("i=%d ans=%lld\n", i, ans);
}
}
printf("%I64d\n", ans);
return ;
}

C

D. Good Triple

这个题目也是求一个满足条件的区间这样的区间有多少个,和上面那个题目的计数的方法特别像。

一个规律就是每九个必然出现一个满足条件s[n]=s[n+k]=s[n+2*k]

计数:从后面往前面推,如果出现一个满足条件的区间,那么可以更新这个右端点,然后用区间长度减去右端点,求出这个右端点到区间端点的长度。

因为这个计数是这个区间长度是只要包含满足条件的这个区间就可以算进去,所以我们一旦找到了满足条件的区间,那么就可以往后推,即使往后推没有找到满足条件的区间,

也没关系,还是可以加上去。这个不仅避免了重复,而且还节约时间。

#include <cstdio>
#include <cstdlib>
#include <queue>
#include <vector>
#include <cstring>
#include <algorithm>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 3e5 + ;
char s[maxn]; int main()
{
scanf("%s", s + );
int len = strlen(s + );
ll ans = ;
int r = len + ;
for(int i=len;i>=;i--)
{
r = min(r, i + );
for(int j=;i+*j<=len;j++)
{
if(s[i]==s[i+j]&&s[i]==s[i+*j])
{
r = min(r, i + * j);
break;
}
}
ans += len - r + ;
}
printf("%I64d\n", ans);
return ;
}

D

dp cf 20190614的更多相关文章

  1. 数位DP CF 55D Beautiful numbers

    题目链接 题意:定义"beautiful number"为一个数n能整除所有数位上非0的数字 分析:即n是数位所有数字的最小公倍数的倍数.LCM(1到9)=2520.n满足是252 ...

  2. DP CF 319 div1B

    http://codeforces.com/contest/319/problem/B 题目大意: 有删除操作,每次都删除数组右边比自己小的.且紧挨着自己的数字.问最小需要删除几次. 思路: 我们定义 ...

  3. dp cf 1700 最近几天的刷题

    C. Number of Ways 这个题目的意思是,把这个n的序列分成三个连续的部分,要求这三个部分的和是一样的.问这种划分的方法有多少种. 这个题目和之前写过的数字划分有点像,这个就是要先进行前缀 ...

  4. dp cf 20190615

    A. Timofey and a tree 这个不算是dp,就是一个思维题,好难想的思维题,看了题解才写出来的, 把点和边分开,如果一条边的两个点颜色不同就是特殊边,特殊边两边连的点就叫特殊点, 如果 ...

  5. dp cf 20190613

    A. Boredom 这个题目不难,但是我做的还比较复杂,不过还是很开心,至少做出来了,开始因为爆int了还wa了一发,搞得我以为自己做错了 #include <cstdio> #incl ...

  6. 数位dp入门 HDU 2089 HDU 3555

    最基本的一类数位dp题,题目大意一般是在a~b的范围,满足某些要求的数字有多少个,而这些要求一般都是要包含或者不包含某些数字,或者一些带着数字性质的要求,一般来说暴力是可以解决这一类问题,可是当范围非 ...

  7. Codeforces 295C Greg and Friends

    BFS+DP.dp[i][j][0]表示有i个50kg,j个100kg的人在左岸,dp[i][j][1]表示有i个50kg,j个100kg的人在右岸.用BFS求最短路的时候记录到达该状态的可能情况. ...

  8. 题解 AT2390 【Games on DAG】

    题目大意 给出一个n个点m条边的DAG,记为G. 可以删掉若干条边成为G′,显然有 2m 种不同的G′. 连边保证:若有 (xi →yi​) 边,则 xi​ < yi . 初始点1和点2有一个标 ...

  9. 做题记录 To 2019.2.13

    2019-01-18 4543: [POI2014]Hotel加强版:长链剖分+树形dp. 3653: 谈笑风生:dfs序+主席树. POJ 3678 Katu Puzzle:2-sat问题,给n个变 ...

随机推荐

  1. 一个不错的spring 学习博客

    http://www.iteye.com/blogs/subjects/spring-tittle-tattle

  2. .Net Core MVC 基于Cookie进行用户认证

    在打代码之前先说一下思路. 登录的的时候服务端生成加密的字符串(用户名.id.当前时间)并且存入客户端cookie中,服务端的缓存中.对客户端的每次请求进行拦截,解密保存在cookie中的加密字符串. ...

  3. 如何将一个div水平垂直居中?6种方法做推荐

    方案一: div绝对定位水平垂直居中[margin:auto实现绝对定位元素的居中], 兼容性:,IE7及之前版本不支持 div{ width: 200px; height: 200px; backg ...

  4. 在VS Code下配置Julia

    原来尝试用Sublime text3配置Julia,但是老是会出一些问题,所以直接在VS code下配置了 1.下载Julia 2.安装,安装过程和其他得软件安装一样,可以改变安装路径 3.安装完成后 ...

  5. .NET Core 发布时去掉多余的语言包文件夹

    用 .NET Core 3.x 作为目标框架时发布完之后,会发现多了很多语言包文件夹,类似于: 有时候,不想要生成这些语言包文件夹,需要稍微配置一下. 在 PropertyGroup 节点中添加如下的 ...

  6. 架构师修炼之微服务部署 - Docker简介

    Docker简介 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器或Windows 机器上,也可以实现虚拟化,容器是 ...

  7. 详解 缓冲区(Buffer 抽象类)

    在本篇博文中,本人主要讲解NIO 的两个核心点 -- 缓冲区(Buffer) 和 通道 (Channel)之一的 缓冲区(Buffer), 有关NIO流的其他知识点请观看本人博文<详解 NIO流 ...

  8. vue-element-admin执行npm install 报错

    如果你出现这类报错: 那么恭喜你,因为这个问题很好解决. ----------------------- 解决方法: git config --global url."https://&qu ...

  9. 挑战全网最幽默的Vuex系列教程:第五讲 Vuex的小帮手

    先说两句 前面已经讲完了 Vuex 下的 State.Getter.Mutation 及 Action 这四驾马车,不知道大家是否已经理解.当然,要想真正熟练掌握的话,还是需要不断的练习和动手实践才行 ...

  10. Sublime text 3快捷键壁纸版