dp cf 1700 最近几天的刷题
这个题目的意思是,把这个n的序列分成三个连续的部分,要求这三个部分的和是一样的。问这种划分的方法有多少种。
这个题目和之前写过的数字划分有点像,这个就是要先进行前缀和的处理,然后找到s/3 和 2*s/3 这两个位置。
因为这个有负数,所以有可能出现,2*s/3 的位置在 s/3 的位置之后,所以这个时候就需要进行处理。
我们每一个 s/3 去找到 2*s/3 的所有合法位置即可。
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 5e5 + ;
ll a[maxn], sum[maxn];
int x[maxn], y[maxn]; int main()
{
int n;
ll S = ;
scanf("%d", &n);
for(int i=;i<=n;i++)
{
scanf("%lld", &a[i]);
sum[i] = sum[i - ] + a[i];
S += a[i];
}
if (S % != ) {
printf("0\n");
return ;
}
S /= ;
int tot = , cnt = ;
for(int i=;i<n;i++)
{
if (sum[i] == S) x[tot++] = i;
if (sum[i] == * S) y[cnt++] = i;
}
if(tot==||cnt==)
{
printf("0\n");
return ;
}
ll ans = ;
for(int i=;i<tot;i++)
{
ll len = upper_bound(y, y + cnt, x[i]) - y;
ans += (cnt - len);
}
printf("%lld\n", ans);
return ;
}
C
这个题目是一个很简单的线性dp。
题目大意:土拨鼠吃花,对于白花,它只吃数量恰好为k这么多的白花,不然就不吃,它给你一个区间从a到b,表示花的数量从a到b,求土拨鼠吃花的方案数。
这个和之前寒假回来后的选拔赛的dp是一样的,因为这个和顺序也有关,所以要先枚举背包容量,然后再去枚举种类,如果和放入背包的顺序无关,就是先枚举种类再去枚举数量。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#define inf 0x3f3ff3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 1e5 + ;
const ll mod = 1e9 + ;
ll dp[maxn];
ll sum[maxn]; int main()
{
int t, k;
scanf("%d%d", &t, &k);
dp[] = ;
for (int i = ; i <= maxn; i++) {
if (i >= k) {
dp[i] = dp[i - ] + dp[i - k];
dp[i] %= mod;
}
else {
dp[i] = dp[i - ];
dp[i] %= mod;
}
}
for(int i=;i<=maxn;i++)
{
sum[i] = sum[i - ] + dp[i];
sum[i] %= mod;
}
while(t--)
{
int a, b;
scanf("%d%d", &a, &b);
ll ans = (sum[b] - sum[a - ] + mod) % mod;
printf("%lld\n", ans);
}
return ;
}
D
题目大意:您的任务是找到a的最长子段,这样可以从子段中最多更改一个数字(将一个数字更改为您想要的任何整数),以使子段严格增加。
这个就是处理一下 对于第 i 个值,求出以 i 为起点的递增序列的长度,以 i 为终点的递增序列长度。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#define inf 0x3f3ff3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 1e5 + ;
ll a[maxn], dp1[maxn], dp2[maxn]; int main()
{
int n;
scanf("%d", &n);
a[] = -inf;
for (int i = ; i <= n; i++) {
scanf("%lld", &a[i]);
dp1[i] = ;
dp2[i] = ;
}
ll mx = ;
for (int i = ; i <= n; i++) {
if (a[i] > a[i - ]) dp1[i] = dp1[i - ] + ;
mx = max(dp1[i], mx);
}
for (int i = n - ; i >= ; i--) {
if (a[i] < a[i + ]) dp2[i] = dp2[i + ] + ;
//printf("dp2[%d]=%lld\n", i, dp2[i]);
}
ll ans = ;
for(int i=;i<=n;i++)
{
if (a[i - ] <= a[i + ] - ) ans = max(ans, dp1[i - ] + dp2[i + ] + );
}
if (mx < n) mx++;
ans = max(ans, mx);
printf("%lld\n", ans);
return ;
}
A
这个题目我觉得有点难,就是找到一个长度恰好为m的k个区间,然后这k个区间求和,使得和最大。
这个n,m,k都比较小,所以可以定义一个二维的,这个和之前的奶牛的题目有点类似https://www.cnblogs.com/EchoZQN/p/11043552.html
这个是lj给了我这个dp状态的定义,我才写出来转移方程的
dp[i][j] 表示前面 i 个数,选了j个区间的最大和。
所以这个转移方程就是 如果我们选了第i个数 那么 dp[i][j]=max(dp[i-m][j-1],dp[i][j])
如果我们不选第 i 个数 那么 dp[i][j]=max(dp[i][j],dp[i-1][j])
这个都写出来了,就很好写了。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#define inf 0x3f3ff3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 1e5 + ;
ll sum[maxn], a[maxn], dp[][]; int main()
{
int n, m, k;
scanf("%d%d%d", &n, &m, &k);
for (int i = ; i <= n; i++) {
scanf("%lld", &a[i]);
sum[i] = sum[i - ] + a[i];
}
for(int i=;i<=n;i++)
{
for(int j=;j<=k;j++)
{
if (i >= m) {
dp[i][j] = max(dp[i - m][j - ] + sum[i] - sum[i - m], dp[i][j]);
dp[i][j] = max(dp[i - ][j], dp[i][j]);
}
else dp[i][j] = dp[i - ][j];
}
}
printf("%lld\n", dp[n][k]);
return ;
}
C
这个题目不是很难,但是需要想一想。
首先,我们优先考虑这个数的长度,然后再考虑这个数的大小。
所以我们可以先由这个最小的数求出长度,然后再去找这个长度如果不整除,那就尽量选更大的。
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 1e6 + ;
int b[maxn];
int a[]; int main()
{
int V;
scanf("%d", &V);
int mn = inf;
for (int i = ; i <= ; i++) {
scanf("%d", &a[i]);
mn = min(mn, a[i]);
}
if (V < mn) {
printf("-1\n");
return ;
}
//printf("mn=%d\n", mn);
int tot = ;
int len = V / mn;
int M = V % mn;
int mx = mn + M;
while(len--)
{
//printf("len=%d mx=%d\n", len, mx);
int flag = ;
for(int i=;i>=;i--)
{
if(a[i]<=mx)
{
flag = i;
b[tot++] = i;
break;
}
}
mx -= (a[flag] - mn);
}
for (int i = ; i < tot; i++) printf("%d", b[i]);
printf("\n");
return ;
}
B
dp cf 1700 最近几天的刷题的更多相关文章
- $2019$ 暑期刷题记录1:(算法竞赛DP练习)
$ 2019 $ 暑期刷题记录: $ POJ~1952~~BUY~LOW, BUY~LOWER: $ (复杂度优化) 题目大意:统计可重序列中最长上升子序列的方案数. 题目很直接的说明了所求为 $ L ...
- DP刷题记录(持续更新)
DP刷题记录 (本文例题目前大多数都选自算法竞赛进阶指南) TYVJ1071 求两个序列的最长公共上升子序列 设\(f_{i,j}\)表示a中的\(1-i\)与b中色\(1-j\)匹配时所能构成的以\ ...
- DP刷题记录
目录 dp刷题记录 codeforces 706C codeforces 940E BZOJ3997 POJ2279 GYM102082B GYM102082D codeforces132C L3-0 ...
- 湾区求职分享:三个月刷题拿到 Google offer,欢迎踊跃提问
本文仅以个人经历和个人观点作为参考.如能受益,不胜荣幸. 本文会不断的修正,更新.希望通过大家的互动最后能写出一份阅者受益的文章. 本文纯手打,会有错别字,欢迎指出,虚心接受及时更改. 小马过河,大牛 ...
- XidianOJ 1020 ACMer去刷题吧
题目描述 刷题是每个ACMer必由之路,已知某oj上有n个题目,第i个题目小X能做对的概率为Pi(0<=Pi<=1,1<=i<=n) 求小X至少做对k道题的概率 输入 第一行输 ...
- NOI题库刷题日志 (贪心篇题解)
这段时间在NOI题库上刷了刷题,来写点心得和题解 一.寻找平面上的极大点 2704:寻找平面上的极大点 总时间限制: 1000ms 内存限制: 65536kB 描述 在一个平面上,如果有两个点( ...
- 一次失败的刷题经历:[LeetCode]292之尼姆游戏(Nim Game)(转)
最近闲来无事刷LeetCode,发现这道题的Accept Rate还是挺高的,尝试着做了一下,结果悲剧了,把过程写下来,希望能长点记性.该题的描述翻译成中文如下: 你正在和你的朋友玩尼姆游戏(Nim ...
- 【刷题记录】BZOJ-USACO
接下来要滚去bzoj刷usaco的题目辣=v=在博客记录一下刷题情况,以及存一存代码咯.加油! 1.[bzoj1597][Usaco2008 Mar]土地购买 #include<cstdio&g ...
- POJ 水题(刷题)进阶
转载请注明出处:優YoU http://blog.csdn.net/lyy289065406/article/details/6642573 部分解题报告添加新内容,除了原有的"大致题意&q ...
随机推荐
- MVC实用笔记
---------------------------- 渲染一个Action:@{Html.RenderAction("Rulelist", "AjaxReuqestD ...
- Spring Security认证提供程序
1.简介 本教程将介绍如何在Spring Security中设置身份验证提供程序,与使用简单UserDetailsService的标准方案相比,提供了额外的灵活性. 2. The Authentica ...
- FZU2216【二分】
题意: 百度. 思路: 一个连续数组111222233344444555666的每一个起伏转折即需要一张万能牌. 然后二分一下得最长区间. #include<cstdio> #includ ...
- ZOJ2868【折半】
题意: 把一堆数分成两堆,使得两堆的差值最小. 思路: 先把一堆数分成两堆,然后用个set存一堆的所有组合,枚举第一堆的状态,二分查找第二堆接近half_value. 瞎说时间复杂度:O(2^17*3 ...
- hdu1506 直方图中最大的矩形 单调栈入门
hdu1506 直方图中最大的矩形 单调栈入门 直方图是由在公共基线对齐的矩形序列组成的多边形.矩形具有相同的宽度,但可能具有不同的高度.例如,左侧的数字显示了由高度为2,1,4,5,1,3,3的矩形 ...
- React入门看这篇就够了
摘要: 很多值得了解的细节. 原文:React入门看这篇就够了 作者:Random Fundebug经授权转载,版权归原作者所有. React 背景介绍 React 入门实例教程 React 起源于 ...
- HTTPRunner实践二——参数化之生成UUID
接口测试中,需要使用到UUID,用来生成唯一ID. 1.什么是UUID UUID是128位的全局唯一标识符,通常由32字节的字符串表示.它可以保证时间和空间的唯一性,也称为GUID,全称为:UUID ...
- Mysql相关函数使用和总结(liet、right、substring、substring_index)
一.字段截取 1.从左开始截取字符串 用法:left(str,length),即:leift(被截取字符串,截取长度) 列子:select left(‘www.baidu.com’,8) 结果:www ...
- MySQL事务学习
- Jmeter 的 vars 和 props 用法
meter 的 JSR223 控件是 代替 BeanShell 的新一代脚本控件,支持多种脚本语言,尤其是其中的 Groovy,更是重点推荐使用的脚本语言,本文研究其中的 vars 和 props 两 ...