ccf 201809-4 再卖菜
题意:
问题描述
在一条街上有n个卖菜的商店,按1至n的顺序排成一排,这些商店都卖一种蔬菜。
第一天,每个商店都自己定了一个正整数的价格。店主们希望自己的菜价和其他商店的一致,第二天,每一家商店都会根据他自己和相邻商店的价格调整自己的价格。具体的,每家商店都会将第二天的菜价设置为自己和相邻商店第一天菜价的平均值(用去尾法取整)。
注意,编号为1的商店只有一个相邻的商店2,编号为n的商店只有一个相邻的商店n-1,其他编号为i的商店有两个相邻的商店i-1和i+1。
给定第二天各个商店的菜价,可能存在不同的符合要求的第一天的菜价,请找到符合要求的第一天菜价中字典序最小的一种。
字典序大小的定义:对于两个不同的价格序列(a1, a2, …, an)和(b1, b2, b3, …, bn),若存在i (i>=1), 使得ai<bi,且对于所有j<i,aj=bj,则认为第一个序列的字典序小于第二个序列。
输入格式
输入的第一行包含一个整数n,表示商店的数量。
第二行包含n个正整数,依次表示每个商店第二天的菜价。
输出格式
输出一行,包含n个正整数,依次表示每个商店第一天的菜价。
样例输入
8
2 2 1 3 4 9 10 13
样例输出
2 2 2 1 6 5 16 10
数据规模和约定
对于30%的评测用例,2<=n<=5,第二天每个商店的菜价为不超过10的正整数;
对于60%的评测用例,2<=n<=20,第二天每个商店的菜价为不超过100的正整数;
对于所有评测用例,2<=n<=300,第二天每个商店的菜价为不超过100的正整数。
请注意,以上都是给的第二天菜价的范围,第一天菜价可能会超过此范围。
分析及思路:
这道题是非常经典的最短路解差分约束问题,然而考试的时候发了草稿纸却没有拿笔,没看出来一开始还以为考的dp,索性直接暴力dfs一波,然而dfs也写搓了,只有30分,回来拿笔一列,我擦,居然是差分约束。
先讲讲差分约束为什么可以用最短路求:
首先,只有二元一次不等式建立的差分约束才能用最短路求解,因为图中的两个点是一一对应建立关系的。
举个例子,对于xj-xi≤k,这样的不等式非常像最短路的松弛操作,假设我们有两个点,i和j,在最短路中会有转移方程if(dist[j]-dist[i]>k),dist[j]=dist[i]+k;,看出来了吧,当前i到j有一条边权值为k,这是相当于对j更新,原来的dist[j]不满足约束条件,也就是dist[j]-dist[i]>k,更新后一定满足约束条件,更新后的dist[j]就满足dist[j]-dist[i]≤k,dist[i]就相当xi,也就是xj-xi≤k!而且这个更新后得到的序列是字典序最大的,为什么?很简单,因为当dist[j]-dist[i]>k时让dist[j]-dist[i]≤k,dist[j]可以更新到dist[i]+k-n,n可以取任意正整数都满足条件,但这里的更新就相当于n取零,使得dist[j]有最大值。
然而这道题要求字典序最小,怎么办呢?很简单,我们把所有的不等式都变成xi-xj≥k,反过来求最长路即可,跟最短路的原理是一模一样的,这里不多论述关于差分约束的讲解,网上有大量教程。
接下来讲如何建图的问题:
首先这里的不等式是这样的:
假设n=5,则有:
- a1* 2≤ x1+x2 ≤ a1* 2+1
- a2* 3≤ x1+x2+x3 ≤ a2* 3+2
- a3* 3≤ x2+x3+x4 ≤ a3* 3+2
- a4* 3≤ x3+x4+x5 ≤ a4* 3+2
- a5* 2≤ x4+x5 ≤ a5* 2+1
- x1≥1
- x2≥1
- x3≥1
- x4≥1
- x5≥1
xi为第一天第i家店的售价,ai为第二天第i家点的售价。
不难发现存在3元一次不等式怎么办呢?我们可以引入中间变量si=x0+x1+…+xi,这里的x0等于0;
即可将上面的第一个不等式转化成: a1* 2≤ s2-s0 ,a1* 2+1≤s0-s2.其它的也一样,不一一列举,全部转化成大于等于的形式,sj-si≥k,i到j建立一条权值为k的单向边,然后spfa跑最长路即可,这里的spfa与原来的spfa有些区别,在spfa之前记得将所有点加入队列,并且dist置0,因为差分约束系统不保证图是连通的,所以要先建立一个虚拟节点,这个虚拟节点为源点,向所有边连接一条权值为0的有向边,以上的操作便是人工省略了虚拟源点的步骤。
有关于差分约束的更多问题可以上网找博客看。
提交官网结果:
AC代码:
#include<iostream>
#include<queue>
#include<cstring>
#define rep(i,x,n) for(int i=x;i<n;i++)
using namespace std;
//head
struct Edge{int to,next,v;}edge[2006];
int n,cur=0,a[306],head[306],dist[306],inq[306],vis[306];
void addedge(int x,int y,int v){edge[cur].to=y;edge[cur].next=head[x];edge[cur].v=v;head[x]=cur++;}
void spfa()
{queue<int>qq;rep(i,0,n+1){qq.push(i);vis[i]=1;dist[i]=0;inq[i]=1;}while(!qq.empty()){int x=qq.front();qq.pop();inq[x]++;vis[x]=0;if(inq[x]>n){cout<<"noanswer"<<endl;return ;}for(int i=head[x];i!=-1;i=edge[i].next){int nx=edge[i].to;if(dist[nx]<dist[x]+edge[i].v){dist[nx]=dist[x]+edge[i].v;if(!vis[nx]){vis[nx]=1;qq.push(nx);}}}}return ;
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);memset(head,-1,sizeof(head));cin>>n;rep(i,1,n+1)cin>>a[i];rep(i,0,n-2){addedge(i+3,i,-(a[i+2]*3+2));addedge(i,i+3,a[i+2]*3);}addedge(2,0,-(a[1]*2+1));addedge(0,2,a[1]*2); //对开始两个单独处理addedge(n,n-2,-(a[n]*2+1));addedge(n-2,n,a[n]*2); //对结尾两个单独处理rep(i,1,n+1)addedge(i-1,i,1); //每个数都要大于等于1spfa();a[1]=dist[1];rep(i,2,n+1)a[i]=dist[i]-dist[i-1];cout<<a[1];rep(i,2,n+1)cout<<' '<<a[i];return 0;
}
ccf 201809-4 再卖菜相关推荐
- CCF201809-4 再卖菜
问题描述: 试题编号: 201809-4 试题名称: 再卖菜 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 在一条街上有n个卖菜的商店,按1至n的顺序排成一排,这些商店都卖一 ...
- CCF201809-4 再卖菜(100分)【DFS】
试题编号: 201809-4 试题名称: 再卖菜 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 在一条街上有n个卖菜的商店,按1至n的顺序排成一排,这些商店都卖一种蔬菜. 第 ...
- [差分约束] AcWing-393 雇佣收银员 AcWing-2128 狡猾的商人 AcWing-3265 再卖菜
差分约束的大概样子 (大概) 差分约束一般是由特殊的n元一次不等式组组成的,它包含N个变量X1-Xn和M个约束条件,而且每个约束条件都是由两个变量做差组成的,形如,其中的ck是常数,它需要我们找到一组 ...
- CCF 差分约束--201809再卖菜
问题描述 在一条街上有n个卖菜的商店,按1至n的顺序排成一排,这些商店都卖一种蔬菜. 第一天,每个商店都自己定了一个正整数的价格.店主们希望自己的菜价和其他商店的一致,第二天,每一家商店都会根据他自己 ...
- 180904 再卖菜 ccf
思路 dfs+去重 关键 满分的关键在于不同的前缀可能会遇到相同的情况,要直接排除这些情况,避免重复计算(单纯dfs只有80分) 实现 这里采用数组f来记录各种情况,通过traceback函数回溯 1 ...
- CCF201809-4 再卖菜
问题描述: AC代码: 1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include ...
- [csp-201809-4]再卖菜 差分约束or记忆化搜索
先更新第一个做法:差分约束 转化成最长路,求出的每一个解是满足差分方程的最小值 spfa求最短路 对于边(x->y) 有: 1 if(dis[y] > dis[x] + a[i].d) d ...
- CSP认证201809-4 再卖菜[C++题解]:差分约束、前缀和
文章目录 题目解答 题目链接 题目解答 来源:acwing 分析: 对于a0,a1,...,ana_0, a_1,...,a_na0,a1,...,an,经过计算相邻的数的平均值得到b0,b1, ...
- 【CCF】 201809-1 卖菜
试题编号: 201809-1 试题名称: 卖菜 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 在一条街上有n个卖菜的商店,按1至n的顺序排成一排,这些商店都卖一种蔬菜. 第一天,每个商 ...
- CCF CSP 201809-1 卖菜
题目链接:http://118.190.20.162/view.page?gpid=T79 问题描述 试题编号: 201809-1 试题名称: 卖菜 时间限制: 1.0s 内存限制: 256.0MB ...
最新文章
- 《Excel 职场手册:260招菜鸟变达人》一第 20 招 怎样在单元格文字前加空白
- Angular filter test
- Java Web 九大内置对象(一)
- 7个HTML你可能不知道的使用技巧
- Spring框架学习3:bean元素属性
- mvc中嵌入html,MVC Razor与javascript混编(js中嵌入razor)
- js已知文件路径得到file对象_Node之文件流与文件路径操作
- 计算32768晶体的负载电容,与晶体手册电容匹配
- python中base函数_详细的python basemap中各函数的所有参量注释
- 逐点插入法-delaunay三角剖分
- superset详解(二)--sql工具箱
- 最优化八:高斯牛顿法、LM法
- 公共基础知识:诸子百家之道家
- 大义灭亲!博士生举报导师抄袭自己的研究成果,学校的操作亮了
- 计算机毕业设计ssm论文管理系统
- HTML5响应式网页设计笔记
- 王道操作系统课代表 - 考研计算机 第三章 内存管理 究极精华总结笔记
- VQA的应用(调研)
- ArcGIS栅格计算器
- 防蓝光爱大爱手机眼镜效果好吗?