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. Java入门系列之线程池ThreadPoolExecutor原理分析思考(十五)

    前言 关于线程池原理分析请参看<http://objcoding.com/2019/04/25/threadpool-running/>,建议对原理不太了解的童鞋先看下此文然后再来看本文, ...

  2. 【一统江湖的大前端(9)】TensorFlow.js 开箱即用的深度学习工具

    示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:<大史住在大前端>原创博文目录 目录 一. 上手TensorFlow.js 二. ...

  3. 复杂Excel转换与导入

    需求 把不同客户提供Excel 直接导入到系统中生成对应的收货单或是出货单.后端创建收货端和出货单的接口已经有现成的webservice或是标准的xml:这类需要做的就是把客户提供不同种类的Excel ...

  4. redis 浅谈事务

    写在前面的话 之前在某个网站上看到一个问题:redis在什么情况下出现事务不会滚的情况,以此为由并结合redis官方文档整理这边笔记.不足之处,请指出,谢谢. 事务 redis支持事务,提供两条重要的 ...

  5. Python程序设计 实验 1 熟悉 IDLE 和在线编程平台

    ------------恢复内容开始------------ 安徽工程大学 Python程序设计 实验报告 班级   物流191   姓名  姚彩琴  学号3190505129 成绩 日期     2 ...

  6. 【特征检测】BRISK特征提取算法

    [特征检测]BRISK特征提取算法原创hujingshuang 发布于2015-07-24 22:59:21 阅读数 17840 收藏展开简介        BRISK算法是2011年ICCV上< ...

  7. TortoiseSVN的使用,以及冲突解决办法

    接下来,试试用TortoiseSVN修改文件,添加文件,删除文件,以及如何解决冲突等. 添加文件 在检出的工作副本中添加一个Readme.txt文本文件,这时候这个文本文件会显示为没有版本控制的状态, ...

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

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

  9. CLDAPReflectionDDoS(CLDAP反射放大攻击)

    CLDAP Reflection DDoS 0x01 LDAP: 全称为Lightweight Directory Access Protocol,即轻量目录访问协议,基于X.500标准: 目录服务就 ...

  10. 【学习笔记】 $learn \ from \ failure \ ? ( 雾$

    \(1.\)变量名不要用 \(next\) ,在某些编译器里可能是关键词,可以用 \(nxt\) 代替 \(\\\) \(2.\)在判断某些条件时应该写成 flag = 条件 ? 1 : flag; ...