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. JUC并发编程基石AQS源码之结构篇

    前言 AQS(AbstractQueuedSynchronizer)算是JUC包中最重要的一个类了,如果你想了解JUC提供的并发编程工具类的代码逻辑,这个类绝对是你绕不过的.我相信如果你是第一次看AQ ...

  2. 打印图片的属性和实现另存图片功能以及使用numpy

    上一篇我们已经学了如何读取图片的功能了以及和opencv的环境搭建了,今天接着来学习,哈哈哈,今天刚好五一,也没闲着,继续学习. 1. 首先我们来实现打印出图片的一些属性功能, 先来看一段代码: im ...

  3. linux下的信号量PV操作进阶之路

    一.同步和互斥机制 信号量 互斥锁 同步:指多个任务按照约定的先后次序相互配合来完成一件事情. 比如读线程等待写线程写完之后再去读. 二.信号量-P/V操作 P(s)含义: if(信号量>0) ...

  4. 浅析CAS与AtomicInteger原子类

    一:CAS简介 CAS:Compare And Swap(字面意思是比较与交换),JUC包中大量使用到了CAS,比如我们的atomic包下的原子类就是基于CAS来实现.区别于悲观锁synchroniz ...

  5. 开始appium的第一个脚本

    设置DesiredCapabilities 存在于以下库中: org.openqa.selenium.remote.DesiredCapabilities Desired Capabilities告诉 ...

  6. 吃瓜的正确姿势,Python绘制罗志祥词云图

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 这篇文章中向大家介绍了Python绘制词云的方法,不难看出绘制词云可以说是一 ...

  7. JDBC 工具类封装

    每次使用jdbc 我们都要 加载驱动类 创建链接 创建Statement 接口对象执行sql 关闭资源 按照这样的套路可以封装一些重用代码方便在其他方法中调用 package com.xzlf.jdb ...

  8. 关于unix环境高级编程、Linux程序设计两部书浅谈

    unix环境高级编程的术语很多,概念内容,也很多,不过学习概念性质.标准规则类的东西,想必都是这样吧——需要进行拓展的内容很多. Linux程序设计,图文并茂,代码量够足,看起来,感觉难度还可以. l ...

  9. C语言字符数组超细讲解

    看到标题,有不少朋友会想:字符数组不也是数组吗?为什么要单独拿出来讲哩?莫非它是朵奇葩? 哈哈,确实,一起来认识一下这朵数组界的奇葩吧! 一.字符数组的定义.引用.初始化 大家好!我是字符数组,看我的 ...

  10. python学习23之标准库

    '''''''''标准库1.datetime 日期时间模块存在于Lib/datetime.py文件内'''from datetime import datetime,date,time #from d ...