T1:

  直接模拟,详见代码注释。

  复杂度$O(NM)$。

Code:

#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
const int N=;
const int M=;
int n,m,tot=;
int a[N][N];
int u[M],d[M],l[M],r[M],bl[M];//上下左右边界及水箱编号
vector<int> v[M],bx[N],by[N];//v做临接表,bx和by存储水箱边界
int get()
{
char c=getchar();
while(c!='.'&&c!='-'&&c!='|'&&c!='+'&&(c<''||c>''))
c=getchar();
if(c>=''&&c<='') return c-'';//水箱编号
else if(c=='-') return -;//横向管道
else if(c=='|') return -;//纵向管道
else if(c=='+') return -;//管道转折,其实和前两个一样,可以不做区分
else return -;//空格子
}
void find(int id,int x,int y)//二分查找水箱边界
{
int xx,yy;
yy=lower_bound(bx[x].begin(),bx[x].end(),y)-bx[x].begin();
r[id]=bx[x][yy];l[id]=bx[x][yy-];
xx=lower_bound(by[y].begin(),by[y].end(),x)-by[y].begin();
d[id]=by[y][xx];u[id]=by[y][xx-];
}
void clean(int id)//将整个水箱的区域都标上该水箱的编号
{
for(int i=u[id];i<=d[id];i++){
for(int j=l[id];j<=r[id];j++)
a[i][j]=id;
}
}
int walk(int x,int y)//沿管道寻找
{
a[x][y]=-;
if(a[x+][y]>) return a[x+][y];//水箱成树形
if(a[x+][y]<=-&&a[x+][y]>=-) return walk(x+,y);
if(a[x][y+]<=-&&a[x][y+]>=-) return walk(x,y+);
if(a[x][y-]<=-&&a[x][y-]>=-) return walk(x,y-);
}
void work(int id)
{
for(int i=d[id];i>=u[id];i--){//水必定先进入靠下的水箱,所以从下到上枚举
if(a[i][l[id]-]<=-&&a[i][l[id]-]>=-)
v[id].push_back(walk(i,l[id]-));
if(a[i][r[id]+]<=-&&a[i][r[id]+]>=-)
v[id].push_back(walk(i,r[id]+));
}
}
void print(int id)//按水箱高度递归输出
{
for(int i=;i<v[id].size();i++)
print(v[id][i]);
printf("%d\n",id);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
a[i][j]=get();//获取格子类型
if(a[i][j]>=&&a[i][j-]>=){//注意水箱编号大于一位的情况
a[i][j]+=*a[i][j-];//用类似快读的思想
a[i][j-]=-;//每个水箱内只能有一个数字
}
if(a[i][j]>=-&&a[i][j]<=-){//将水箱边界存入
bx[i].push_back(j);
by[j].push_back(i);
}
}
}
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
if(a[i][j]>=){
bl[++tot]=a[i][j];//记录水箱编号,水箱编号可能不连续
find(a[i][j],i,j);//寻找水箱边界
}
}
}
for(int i=;i<=tot;i++) clean(bl[i]);
for(int i=;i<=tot;i++) work(bl[i]);
print();
return ;
}

T1

T2:

  DP好题,不过暴力也能A。

  题目大意:一条线上N个点,共有精灵M个,时间为一时位于K,精灵都有价值,但一段时间后会消失,求收获的最大权值。

  DP(正解):

  

  搜索(暴力):

  

  暴力压正解,我就不说什么了…………

  下面说DP:搜索可以自己想

    设DP数组f[i][j][k],表示i~j已经走过,目前位于i的最大值。

    由于抓取精灵不需要时间,而且权值均为正,所以每次遇到精灵一定会抓。

    先对精灵按照坐标排序。

    将精灵的坐标连同起始点离散,初始化为负无穷,时间为一时起点处权值赋为0。

    这是一个区间DP,先枚举时间,然后枚举区间长度,再枚举左端点,算出右端点。

    然后我们就可以开心地DP了:

      i为时间,L为左端点,R为右端点,val代表精灵的权值,p代表精灵的位置,t为精灵消失的时间。

      f[L-1][R][i+1]=max(f[L-1][R][i+1],f[L][R][i]+val[L-1])  (i+p[L]-p[L-1]<=t[L-1])

      f[L-1][R][i+1]=max(f[L-1][R][i+1],f[L][R][i])      (i+p[L]-p[L-1]>t[L-1])

      f[R+1][L][i+1]=max(f[R+1][L][i+1],f[R][L][i]+val[R+1])  (i+p[R+1]-p[R]<=t[R+1])

      f[R+1][L][i+1]=max(f[R+1][L][i+1],f[R][L][i])      (i+p[R+1]-p[R]>t[R+1])

      f[R+1][L][i+1]=max(f[R+1][L][i+1],f[L][R][i]+val[R+1])  (i+p[R+1]-p[L]<=t[R+1])

      f[R+1][L][i+1]=max(f[R+1][L][i+1],f[L][R][i])      (i+p[R+1]-p[L]>t[R+1])

      f[L-1][R][i+1]=max(f[L-1][R][i+1],f[R][L][i]+val[L-1])  (i+p[R]-p[L-1]<=t[L-1])

      f[L-1][R][i+1]=max(f[L-1][R][i+1],f[R][L][i])      (i+p[R]-p[L-1]>t[L-1])

    后四行的转移方程代表从区间的一头走到另一头再扩展区间,不能丢。

    起点算作一只贡献为0的精灵,方便判断。

    注意判断在该时间内精灵是否已消失。

    DP过程中不断对ans取max,最后的max即为答案。

    共有M只精灵,时间的最大值为T。

    时间复杂度$O(M^2T)$

Code:

 #include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=;
const int M=;
const int inf=;
int n,k,m,t=,ans=;
int s[M],dp[M][M][N];
struct point {
int a,b,c;
}p[M];
bool comp(const point a1,const point a2)
{
return a1.a<a2.a;
}
int main()
{
scanf("%d%d%d",&n,&k,&m);
for(int i=;i<=m;i++){
scanf("%d%d%d",&p[i].a,&p[i].b,&p[i].c);
t=max(p[i].c,t);
}
p[++m].a=k;
sort(p+,p+m+,comp);
for(int i=;i<=t;i++){
for(int j=;j<=m;j++){
for(int l=;l<=m-j+;l++){
int r=l+j-;
dp[l][r][i]=dp[r][l][i]=-inf;
}
}
}
for(int i=;i<=m;i++){
s[i]=p[i].a;p[i].a=i;
if(s[i]==k)
dp[i][i][]=p[i].b;
}
for(int i=;i<=t;i++){
for(int j=;j<=m;j++){
for(int l=;l<=m-j+;l++){
int r=l+j-;
if(dp[l][r][i]>=){
if(l>=){
int ti=i+s[l]-s[l-];
if(ti<=p[l-].c)
dp[l-][r][ti]=max(dp[l-][r][ti],dp[l][r][i]+p[l-].b);
else
dp[l-][r][ti]=max(dp[l-][r][ti],dp[l][r][i]);
ans=max(ans,dp[l-][r][ti]);
}
if(r<=m-){
int ti=i+s[r+]-s[l];
if(ti<=p[r+].c)
dp[r+][l][ti]=max(dp[r+][l][ti],dp[l][r][i]+p[r+].b);
else
dp[r+][l][ti]=max(dp[r+][l][ti],dp[l][r][i]);
ans=max(ans,dp[r+][l][ti]);
}
}
if(dp[r][l][i]>=){
if(l>=){
int ti=i+s[r]-s[l-];
if(ti<=p[l-].c)
dp[l-][r][ti]=max(dp[l-][r][ti],dp[r][l][i]+p[l-].b);
else
dp[l-][r][ti]=max(dp[l-][r][ti],dp[r][l][i]);
ans=max(ans,dp[l-][r][ti]);
}
if(r<=m-){
int ti=i+s[r+]-s[r];
if(ti<=p[r+].c)
dp[r+][l][ti]=max(dp[r+][l][ti],dp[r][l][i]+p[r+].b);
else
dp[r+][l][ti]=max(dp[r+][l][ti],dp[r][l][i]);
ans=max(ans,dp[r+][l][ti]);
}
}
}
}
}
printf("%d\n",ans);
return ;
}

T2

建议搜索AC的人打一遍DP,毕竟正经NOIP数据是不会这么水的。

NOIP模拟测试18(T3待更新)的更多相关文章

  1. 2019.8.12 NOIP模拟测试18 反思总结

    写个博客总是符合要求的对吧 回来以后第一次悄悄参加考试,昨天全程围观… 然后喜提爆炸120分wwwwwwwww T1用了全机房最慢的写法,导致改掉死循环T掉的一个点以后还是死活过不了最后一个点.T2全 ...

  2. noip模拟测试18

    打开比赛第一眼--超级树? 点开--原题 百感交集-- 欣喜于发现是半年前做过两遍的原题 紧张于如果A不了比较尴尬 绝望于发现根本不会做了 瞟了一眼t1,瞅了一眼t2,嗯--开始搞t3 10分钟打完暴 ...

  3. NOIP模拟测试18「引子·可爱宝贝精灵·相互再归的鹅妈妈」

    待补 引子 题解 大模拟,注意细节 代码1 #include<bits/stdc++.h> using namespace std; int n,m;char a[1005][1005]; ...

  4. NOIP模拟测试17&18

    NOIP模拟测试17&18 17-T1 给定一个序列,选取其中一个闭区间,使得其中每个元素可以在重新排列后成为一个等比数列的子序列,问区间最长是? 特判比值为1的情况,预处理比值2~1000的 ...

  5. 「题解」NOIP模拟测试题解乱写II(36)

    毕竟考得太频繁了于是不可能每次考试都写题解.(我解释个什么劲啊又没有人看) 甚至有的题目都没有改掉.跑过来写题解一方面是总结,另一方面也是放松了. NOIP模拟测试36 T1字符 这题我完全懵逼了.就 ...

  6. 2019.8.3 [HZOI]NOIP模拟测试12 C. 分组

    2019.8.3 [HZOI]NOIP模拟测试12 C. 分组 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 刚看这题觉得很难,于是数据点分治 k只有1和2两种,分别 ...

  7. 2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色

    2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 数据结构学傻的做法: 对每种颜色开动态开点线段树直接维 ...

  8. 2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci)

    2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci) 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 找规律 找两个节点的lca,需 ...

  9. 「题解」NOIP模拟测试题解乱写I(29-31)

    NOIP模拟29(B) T1爬山 简单题,赛时找到了$O(1)$查询的规律于是切了. 从倍增LCA那里借鉴了一点东西:先将a.b抬到同一高度,然后再一起往上爬.所用的步数$×2$就是了. 抬升到同一高 ...

随机推荐

  1. 【leetcode】990. Satisfiability of Equality Equations

    题目如下: Given an array equations of strings that represent relationships between variables, each strin ...

  2. SQO2008配置管理工具服务显示远程过程调用失败0x800706be

    需要进行删除或更改程序里面,去卸载Microsoft SQL Server 2012 Express LocalDB就可以用了 如果还不可以看,看看是不是还有其它的占用了这个实例名 如: Micros ...

  3. nginx查看变量值

    nginx查看变量值 location / { echo $host; #域名 echo $remote_addr; echo $remote_user; echo $time_local; echo ...

  4. 升级到Xcode 5.1和iOS 7遇到的各种问题及解决办法汇总:

    <iOS 企业证书部署无效的问题>:http://t.cn/8s7ILWZ <clipsToBounds 属性默认值变了>:http://weibo.com/165881473 ...

  5. 优化问题及KKT条件

    整理自其他优秀博文及自己理解. 目录 无约束优化 等式约束 不等式约束(KKT条件) 1.无约束优化 无约束优化问题即高数下册中的 “多元函数的极值"  部分. 驻点:所有偏导数皆为0的点: ...

  6. Python单元测试示例

    这是使用单元测试框架unittest进行的单元测试,并输出测试结果. 首先定义一个类,三个方法.第一个方法是判断两个字符串是否相等,第二个方法是判断结果为真:第三个方法也是判断两个字符串相等. 然后是 ...

  7. java.net.BindException: Address already in use: 解决方法

    java.net.BindException: Address already in use: 解决方法   1. 执行cmd 2. cmd命令模式下输入netstat -ano,然后找到占用端口的那 ...

  8. Openstack组件实现原理 — Keystone认证功能

    目录 目录 前言 Keystone安装列表 Keystone架构 Keystone的管理对象 一个理解Keystone管理对象功能的例子 Keystone管理对象之间的关系 Keystone V3的新 ...

  9. Openstack组件部署 — Overview和前期环境准备

    目录 目录 前言 软件环境 Openstack 简介 Openstack 架构 Openstack Install Overview 创建Node虚拟机 环境准备 基础设置 Install OpenS ...

  10. 【消息中间件】kafka

    一.kafka整体架构 kafka是一个发布订阅模式的消息队列,生产者和消费者是多对多的关系,将发送者与接收者真正解耦: 生产者将消息发送到broker: 消费者采用拉(pull)模式订阅并消费消息: ...