• 2019.03.15 ZJOI2019模拟赛 解题报告


    得分: (20+45+15=80)(三题暴力全写挂。。。)

    (T1):Lyk Love painting

    首先,不难想到二分答案然后(DP)验证。

    设当前需验证的答案为(x),则一个暴力的想法就是设(f_{i,j})表示在第一行选前(i)个数,第二行选前(j)个数使得每个矩形内元素和不超过(x)所需的最少矩形数

    则我们可以预处理出三个数组(lst_{1,i},lst_{2,i},lst_{3,i})来分别表示能使(sum_{j=lst_{1,i}}^ia_{1,i}le x,sum_{j=lst_{2,i}}^ia_{2,i}le x,sum_{j=lst_{3,i}}^ia_{1,i}+a_{2,i}le x)的最小值。

    这样就不难推出转移方程为:

    [f_{i,j}=min(f_{lst_{1,i},j},f_{lst_{2,i},j},f_{lst_{3,i},lst_{3,j}})+1 ]

    其中第三种转移需要满足条件(i=j)

    但这样显然会(TLE),因此需要优化。

    考虑设(f_i)表示在第一行与第二行各选(i)个数使得每个矩形内元素和不超过(x)所需的最少矩形数

    则一个显然的转移就是前面提到过的:

    [f_i=f_{lst_{3,i}}+1 ]

    而还有一种转移有点复杂,却很好理解。

    我们先初始化(t_1=t_2=i),分别表示第一行和第二行选择的元素个数。然后初始化(tot=0),用于存储步数。

    则每次我们选择(t_1)(t_2)中较大的那个(设它为(t_x),若相等则任选),然后把(t_x)更新为(lst_{x,i}),并将(tot)(1)

    然后,我们就可以得到转移方程如下:

    [f_i=f_{max(t_1,t2)}+tot ]

    这应该正确性显然。

    然后加一些小剪枝,例如(t_1=t_2=0)时直接退出,还有当(f_i>m)时直接返回(false)等等,就可过了。

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define RL Reg LL
    #define Con const
    #define CI Con int&
    #define CL Con LL&
    #define I inline
    #define W while
    #define N 100000
    #define M 100
    #define LL long long
    #define Gmax(x,y) (x<(y)&&(x=(y)))
    #define Gmin(x,y) (x>(y)&&(x=(y)))
    #define Init(pos) for(i=1,p=0;i<=n;lst[pos][i++]=p) W(s[pos][i]-s[pos][p]>x) ++p;
    using namespace std;
    int n,m,lst[4][N+5],f[N+5];LL a[4][N+5],s[4][N+5];
    class FastIO
    {
    	private:
    		#define FS 100000
    		#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
    		#define tn (x<<3)+(x<<1)
    		#define D isdigit(c=tc())
    		char c,*A,*B,FI[FS];
    	public:
    		I FastIO() {A=B=FI;}
    		Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
    		Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
    }F;
    I bool Check(CL x)//DP验证答案正确性
    {
    	RI i,j,k,p,t,t1,t2;f[0]=lst[1][0]=lst[2][0]=lst[3][0]=0;//初始化
    	Init(1)Init(2)Init(3)for(i=1;i<=n;++i)//Init预处理lst数组
    	{
    		f[t1=t2=i]=min(m,f[lst[3][i]])+1,t=0;//第一种转移
    		W(++t<=m&&(t1||t2)) (t1>t2?t1=lst[1][t1]:t2=lst[2][t2]),Gmin(f[i],f[max(t1,t2)]+t);//用t1和t2两个变量不断向前跳,更新答案
    		if(f[i]>m) return false;//如果f[i]已经大于m,返回false
    	}return true;
    }
    int main()
    {
    	freopen("paint.in","r",stdin),freopen("paint.out","w",stdout);
    	RI i,j,Mx=0;RL res,STO,hl,ORZ;for(F.read(n,m),i=1;i<=2;++i) for(j=1;j<=n;++j) F.read(a[i][j]),s[i][j]=a[i][j]+s[i][j-1],Gmax(Mx,a[i][j]);//读入,初始化前缀和
    	for(i=1;i<=n;++i) a[3][i]=a[1][i]+a[2][i],s[3][i]=s[1][i]+s[2][i];//用a[3]记录下a[1]与a[2]的和,方便之后的操作
    	STO=Mx,ORZ=s[1][n]+s[2][n];W(STO<=ORZ) Check(hl=STO+ORZ+1>>1)?(res=hl,ORZ=hl-1):STO=hl+1;return printf("%lld",res),0;//二分答案
    }
    

    (T2): Lyk Love convex hull

    一道神仙计算几何+(DP),压根不会订正。

    (T3):Lyk Love music

    一道挺有趣的神仙题,可惜看了题解还是云里雾里。。。

  • 相关阅读:
    TCP/IP协议(一)网络基础知识 网络七层协议
    安卓混合开发——原生Java和H5交互,保证你一看就懂!
    最好用的17个渗透测试工具,全都在这里!(转载)
    【绿盟大讲堂】 渗透测试流程解析
    每日扫盲:eclipse快捷键 包括查找类、方法、变量汇总
    hadoop学习笔记(十):hdfs在命令行的基本操作命令(包括文件的上传和下载和hdfs中的文件的查看等)
    hadoop学习笔记(九):mr2HA高可用环境搭建及处步使用
    github新手使用
    hadoop学习笔记(九):mapReduce1.x和2.x
    hadoop学习笔记(八):hadoop2.x的高可用环境搭建
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/Contest20190315.html
Copyright © 2020-2023  润新知