YYHSOI模拟赛题解(T3种树)

2023-10-18 04:40
文章标签 模拟 t3 题解 种树 yyhsoi

本文主要是介绍YYHSOI模拟赛题解(T3种树),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目描述

为了绿化乡村,H村积极响应号召,开始种树了。

H村里有n幢房屋,这些屋子的排列顺序很有特点,在一条直线上。于是方便起见,我们给它们标上1~n。树就种在房子前面的空地上。

同时,村民们向村长提出了m个意见,每个意见都是按如下格式:希望第li个房子到第ri个房子的房前至少有ci棵树。

因为每个房屋前的空地面积有限,所以每个房屋前最多只能种ki棵树。

村长希望在满足村民全部要求的同时,种最少的树以节约资金。请你帮助村长。

 

 

 

 

 

输入

输入文件名为tree.in

输入第1行,包含两个整数nm

第2行,有n个整数ki

第2~m+1行,每行三个整数lirici

 

 

 

 

 

输出

输出文件名为tree.out

输出1个整数表示在满足村民全部要求的情况下最少要种的树。村民提的要求是可以全部满足的。

 

样例输入

tree.in
5 3
1 1 1 1 1
1 3 2
2 4 2
4 5 1
tree.out
3
tree.in
4 3
3 2 4 1
1 2 4
2 3 5
2 4 6
tree.out
8

样例输出

【输入输出样例解释1】 如图是满足样例的其中一种方案,最少要种3棵树。 、
【输入输出样例解释2】 如图是满足样例的其中两种方案,左图的方案需要种9棵树,右图的方案需要种8棵树。可以验证,最少需要种8棵树。

提示

 

【数据范围】


对于30%的数据,0<n≤100,0<m≤100,ki=1;


对于50%的数据,0<n≤2,000,0<m≤5,000,0<ki≤100;


对于70%的数据,0<n≤50,000,0<m≤100,000,0<ki≤1,000;


对于100%的数据,0<n≤500,000,0<m≤500,000,0<ki≤5,000

 

 

这一道题目,我刚开始也想到了差分约束的做法,但是由于我比较脑残。发现现有的约束条件不够(因为我没有意识到s[i] > s[i-1]),所以一直很难想明白这道题目。所以我选择用贪心,简单地说就是把树尽量地往右边种这样子,后边出现的区间就可以在左边少种树,那么少种的树怎么办?我们就把它往右边种,所以说这个贪心策略是可行的。但是这需要数据结构的优化与变形。而且我在打了80多行的时候,膝盖不小心顶到了关机键。。。然后就放弃治疗了。

但是后来经过方科晨的讲解,我就秒懂了,原来我漏了这个东西。

 

 1 #include <cmath>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 
 7 using namespace std;
 8 
 9 int N,M;
10 int num=0;
11 int vet[2000005];
12 int val[2000005],next1[2000005],head1[2000005];
13 int flag[2000005],q[2000005],dis[2000005];
14 
15 void add(int u,int v,int cost)
16 {
17     vet[++num]=v;
18     val[num]=cost;
19     next1[num]=head1[u];
20     head1[u]=num;
21 }
22 
23 void SPFA(int s)
24 {
25     for (int i=1; i<=N; i++)
26     {
27         dis[i]=1e9;
28         flag[i]=0;
29     }
30     flag[s]=0; dis[s]=0;
31     int t=0; int w=0;
32     q[0]=s;
33     while (t <= w)
34     {
35         int u=q[t];
36         t++;
37         for (int e=head1[u]; e!=-1; e=next1[e])
38         {
39             int cost=val[e];
40             int V=vet[e];
41             if (dis[V] > dis[u] + cost)
42             {
43                 dis[V]=dis[u] + cost;
44                 if (! flag[V])
45                 {
46                     flag[V]=1;
47                     q[++w]=V;
48                 }
49             }
50         }
51         flag[u]=0;
52     }
53     printf("%d\n",abs(dis[N]));
54 }
55 
56 int main()
57 {
58     scanf("%d%d",&N,&M);
59     for (int i=0; i<=N; i++)
60     {
61         head1[i]=-1;
62     }
63     for (int i=1; i<=N; i++)
64     {
65         int X;
66         scanf("%d",&X);
67         add(i-1,i,0);
68         add(i,i-1,X);
69     }
70     for (int i=1; i<=M; i++)
71     {
72         int l,r,z;
73         scanf("%d%d%d",&l,&r,&z);
74         add(l-1,r,-z);
75     }
76     SPFA(0);
77 }
Show My Ugly Code

 

转载于:https://www.cnblogs.com/TUncleWangT/p/7064857.html

这篇关于YYHSOI模拟赛题解(T3种树)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/230231

相关文章

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

usaco 1.2 Transformations(模拟)

我的做法就是一个一个情况枚举出来 注意计算公式: ( 变换后的矩阵记为C) 顺时针旋转90°:C[i] [j]=A[n-j-1] [i] (旋转180°和270° 可以多转几个九十度来推) 对称:C[i] [n-j-1]=A[i] [j] 代码有点长 。。。 /*ID: who jayLANG: C++TASK: transform*/#include<

hdu4431麻将模拟

给13张牌。问增加哪些牌可以胡牌。 胡牌有以下几种情况: 1、一个对子 + 4组 3个相同的牌或者顺子。 2、7个不同的对子。 3、13幺 贪心的思想: 对于某张牌>=3个,先减去3个相同,再组合顺子。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOExcepti

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

每日一题|牛客竞赛|四舍五入|字符串+贪心+模拟

每日一题|四舍五入 四舍五入 心有猛虎,细嗅蔷薇。你好朋友,这里是锅巴的C\C++学习笔记,常言道,不积跬步无以至千里,希望有朝一日我们积累的滴水可以击穿顽石。 四舍五入 题目: 牛牛发明了一种新的四舍五入应用于整数,对个位四舍五入,规则如下 12345->12350 12399->12400 输入描述: 输入一个整数n(0<=n<=109 ) 输出描述: 输出一个整数

C - Word Ladder题解

C - Word Ladder 题解 解题思路: 先输入两个字符串S 和t 然后在S和T中寻找有多少个字符不同的个数(也就是需要变换多少次) 开始替换时: tips: 字符串下标以0开始 我们定义两个变量a和b,用于记录当前遍历到的字符 首先是判断:如果这时a已经==b了,那么就跳过,不用管; 如果a大于b的话:那么我们就让s中的第i项替换成b,接着就直接输出S就行了。 这样

【算法专场】模拟(下)

目录 前言 38. 外观数列 算法分析 算法思路 算法代码 1419. 数青蛙 算法分析 算法思路 算法代码  2671. 频率跟踪器 算法分析 算法思路 算法代码 前言 在前面我们已经讲解了什么是模拟算法,这篇主要是讲解在leetcode上遇到的一些模拟题目~ 38. 外观数列 算法分析 这道题其实就是要将连续且相同的字符替换成字符重复的次数+

模拟实现vector中的常见接口

insert void insert(iterator pos, const T& x){if (_finish == _endofstorage){int n = pos - _start;size_t newcapacity = capacity() == 0 ? 2 : capacity() * 2;reserve(newcapacity);pos = _start + n;//防止迭代