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. alg-最长公共子串

    class Solution { public: const std::vector<std::string> LongestCommonSubstring(const std::stri ...

  2. Java接口和抽象类有什么区别,哪些时候用接口,哪些时候用抽象类?

    Java接口和抽象类有什么区别,哪些时候用接口,哪些时候用抽象类? 2013-01-05 17:16:09|  分类: JAVA |  标签:java  |举报|字号 订阅     下面比较一下两者的 ...

  3. 使用StopWatch类来计时 (perf4j-0.9.16.jar 包里的类)

    public class StopWatch { static public int AN_HOUR = 60 * 60 * 1000; static public int A_MINUTE = 60 ...

  4. 使用Network Emulator Toolkit工具模拟网络丢包测试(上)

    弱网络测试包括延时和丢包二种场景下应用的功能是否正常: 网络延时测试使用Fiddler工具控制上下行数据传输延时时间来模拟网络延时场景: 网络丢包测试使用Network Emulator Toolki ...

  5. 自己写的一个HTML的小网页

    上次在上直播课的时候,教员提到了html这种标记语言.自己就在W3school上面学了一点点关于html的一些皮毛,自己动手写了一个小网页,同时自己对CTF这一块比较感兴趣,但是自己还是一个干干净净的 ...

  6. PHP出现SSL certificate:unable to get local issuer certificate的解决办法

    当本地curl需要访问https时,如果没有配置证书,会出现SSL certificate: unable to get local issuer certificate错误信息. 解决办法: 1.下 ...

  7. Springboot:员工管理之修改员工(十(8))

    构建员工修改请求 com\springboot\controller\EmployeeController.java /*调转到员工修改页 携带员工信息 restful风格*/ @GetMapping ...

  8. Springboot:IDEA重调安装依赖窗口(二)

    Settings-Plugins 搜索Editstarters: 安装完插件 重启idea: 查看安装是否成功: 在pom.xml 右键: 选择热部署依赖 点击ok进行自动装配: 热部署依赖环境已经配 ...

  9. 使用dynamic和MEF实现轻量级的AOP组件 (3)

    转摘 https://www.cnblogs.com/niceWk/archive/2010/07/22/1783068.html 水到渠成 在上一篇的<偷梁换柱>中,介绍了Weavabl ...

  10. 干货最实用的 Python 多线程代码框架

    前言 很多地方都要用到多线程,这是我经常用的多线程代码,放在博客园记录下. 代码 from multiprocessing.pool import ThreadPool thread = 10 ite ...