首页 > 其他分享 >P3344 [ZJOI2015] 幻想乡 Wi-Fi 搭建计划

P3344 [ZJOI2015] 幻想乡 Wi-Fi 搭建计划

时间:2024-03-23 22:34:08浏览次数:30  
标签:now min int Wi ch ZJOI2015 Fi fo define

非常精妙的一个做法。

简化题意:定义合法区域为 \(y \in [0,R]\) 的区域,给定一些在合法区域内的标记点,与一些圆心在合法区域外的,半径为 \(R\) 的圆,选择第 \(i\) 个圆会产生 \(c_i\) 的代价。第一问是最多能覆盖几个标记点;第二问是在保证覆盖标记点最多的情况下,代价的最小值。

首先第一问是非常好做的,明显我们可以选上所有的圆,枚举判断即可,复杂度 \(O(nm)\)。

第二问一上来就给人一种 NP 问题的感觉啊!但是因为每个圆的半径固定,所以是有做法的。

有一个比较明显的结论:假设所有圆都在合法区域的一侧(代码中将“一侧”钦定为上侧),则将圆按照圆心的 \(x\) 从小到大排序,那么假设第 \(i\) 个圆无法覆盖某一个点,那么在 \(i\) 之后的圆也永远无法覆盖到这个点。

这句话其实也点明了去掉无法覆盖点后,排序圆,排序点后,存在匹配关系使得每个圆所覆盖的点都是一段区间。


另起思路,定义 \(f_{i,j,k}\) 为目前处理到第 \(i\) 个点,上一个被匹配的上侧圆为 \(j\),上一个被匹配的下侧圆为 \(k\) 的最小代价。若 \(j=0\) 则表示目前从未匹配过上侧圆,\(k=0\) 亦同。

初始化:\(f_{0,0,0}=0\)。

答案:\(\min_{i=0}^{m}\min_{j=0}^{m}f_{n,i,j}\)。

转移不难,我们考虑枚举一个可以包含 \(i\) 点的圆,然后如果这个圆就是上次被匹配的某侧圆,那么本次转移无代价,否则就加上这个圆的代价。

但是一个圆会有被加代价多次的情况啊!你说得对,但是我们的结论保证永远不会出现这种情况,因为你总会发现一段点匹配一个圆后才会换圆,且永远不会把匹配圆换回来(结论是对称的)。

欢迎 ctj,记得把 namespace gza 改掉。

#include<bits/stdc++.h>
using namespace std;
namespace gza{
	#define int long long
	#define pb push_back
	#define MT int TTT=R;while(TTT--)
	#define pc putchar
	#define R read()
	#define fo(i,a,b) for(int i=a;i<=b;i++)
	#define rep(i,a,b) for(int i=a;i>=b;i--)
	#define m1(a,b) memset(a,b,sizeof a)
	namespace IO
	{
		inline int read()
		{
		    int x=0;
		    char ch=getchar();
		    bool f=0;
		    while(!isdigit(ch)){if(ch=='-') f=1;ch=getchar();}
		    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
		    if(f) x=-x;
		    return x;    
		}
		template<typename T> inline void write(T x)
		{
		    if(x<0) pc('-'),x=-x;
		    if(x>9) write(x/10);
		    pc(x%10+'0');
		}
	};
	using namespace IO;
	
	#define x first
	#define y second
	const int N=110;
	int n,m,r;
	pair<int,int> a[N];
	bool vis[N];
	struct Node{
		int x,y,c,typ;
		bool operator< (const Node& A)const
		{
			return pair<int,int>({x,y})<pair<int,int>({A.x,A.y});
		}
	}b[N];
	bool check(int i,int j)
	{
		if(j==0) return 1;
		int dx=a[i].x-b[j].x,dy=a[i].y-b[j].y;
		return dx*dx+dy*dy<=r*r;
	}
	int f[N][N][N];
	void main(){
		n=R,m=R,r=R;
		fo(i,1,n) a[i].x=R,a[i].y=R;
		fo(i,1,m) b[i].x=R,b[i].y=R,b[i].c=R;
		fo(i,1,m)
			if(b[i].y>r) b[i].typ=1;
			else b[i].typ=2;
		fo(i,1,n)
		{
			bool flag=0;
			fo(j,1,m) if(check(i,j)) flag=1;
			if(!flag) vis[i]=1;
		}
		int now=0;
		fo(i,1,n) if(!vis[i]) now++,a[now]=a[i];
		sort(a+1,a+now+1);
		write(n=now),puts("");
		m1(f,0x3f),f[0][0][0]=0;
		fo(i,1,n) fo(j,0,m) fo(k,0,m) fo(l,1,m) if(check(i,l))
		{
			if(b[l].typ==1) f[i][l][k]=min(f[i][l][k],f[i-1][j][k]+((j!=l)?b[l].c:0));
			else f[i][j][l]=min(f[i][j][l],f[i-1][j][k]+((k!=l)?b[l].c:0));
		}
		int ans=2e9;
		fo(i,0,m) fo(j,0,m) ans=min(ans,f[n][i][j]);
		write(ans);
	}
}
signed main(){
	gza::main();
}

标签:now,min,int,Wi,ch,ZJOI2015,Fi,fo,define
From: https://www.cnblogs.com/acwing-gza/p/18091821

相关文章

  • Windows库链接报错
    问题回溯今天拿到别人已经编译好的库,发现在链接的时候出现了报错[9/912.7/sec]LinkingCXXsharedmodulebin\plugins\AsensingPlugin\AsensingPlugin.dllFAILED:bin/plugins/AsensingPlugin/AsensingPlugin.dllcmd.exe/C"cd.&&"C:\ProgramFiles\CMake\bin\cmake.e......
  • 笔记本连接WiFi没有网络
    现象WiFi显示连接,能够登录QQ微信聊天,可以打开部分网页如百度,B站,但是大部分网页提示网络异常,连接超时等,如下图:解决这种问题大概率是因为IP分配的问题,解决办法如下:win+i打开设置选择网络和Internet进去,高级网络设置选择网络重置,立即重置网络重置选......
  • Windows服务注册-极语言版
    以下代码请新建工程-初级程序-粘贴窗体对象-粘贴代码模块-保存-关闭程序-再打开。在使用编译好的exe代码之前,请先在以管理员模式运行的cmd窗口中执行以下语句:让任意的cmd窗口都可执行sc命令,让sc等命令不需要以管理员权限执行cmd窗口,执行完以下代码之后,需要重启电脑regadd"H......
  • cmake之find_library使用问题
    附上工程源码demo工程PS:这个工程用于导出库CMakeLists.txtcmake_minimum_required(VERSION3.5)project(demoLANGUAGESCXX)set(CMAKE_INCLUDE_CURRENT_DIRON)set(CMAKE_CXX_STANDARD11)set(CMAKE_CXX_STANDARD_REQUIREDON)add_library(demoSHAREDdemo.cpp......
  • web前端之node读取文件夹名称及html文件的标题、文件系统、路径处理、模块、正则、isD
    MENU代码解析代码constfs=require('fs');constpath=require('path');//文件夹路径//C:\mssj\web\web-case\case\nodeJs\index.js//C:\mssj\web\web-case\case\nodeJs\index.html//C:\mssj\web\web-case\case\ajaxProgressMoni......
  • Win10彻底永久关闭自动更新
        win10系统的自动更新可能给我们带来很多困扰,尤其是对于安装了虚拟机的用户,可能导致原来用得很好的两个系统突然之间问题百出,例如虚拟机卡顿或网络不能连通,软件不能兼容,等等。有些问题比较明显,有些问题很隐晦,时有时无,降低用户使用效率。而仅仅通过windows设置来暂停或......
  • 分支和循环(上)if 和switch语句
    一:C语言支持的结构1.顺序结构C语言中的顺序结构是最基本的控制结构,它按照代码的书写顺序,从上到下,从左到右依次执行。在顺序结构中,程序按照代码的书写顺序执行,没有任何的跳转或分支。顺序结构的主要特点是:1.**顺序执行**:程序按照代码的书写顺序,从上到下,从左到右依次执行。......
  • 批处理脚本来将 Windows 10 的虚拟内存设置为自动管理所有驱动器的分页文件大小
    批处理脚本来将Windows10的虚拟内存设置为自动管理所有驱动器的分页文件大小:CopyCode@echooffREM将所有驱动器的分页文件大小设置为自动管理REM禁用虚拟内存wmiccomputersystemwherename="%computername%"setAutomaticManagedPagefile=Falsewmicpagefilesetw......
  • 如何实现Mac与Windows共享文件夹?
    本人使用系统是macos13.1和win11系统亲测使用!第一步确保两台电脑链接相同的WIFI这一步非常关键第二步Windows电脑创建共享文件夹并设置文件共享首先在Window端桌面创建一个共享文件夹。(也可以自己更改需要存储的路径)接着右键属性--选择共享--高级共享--勾选共......
  • 把 Windows 装进 Docker 容器里
    本篇文章聊聊如何在Docker里运行Windows操作系统,WindowsinDockerContainer(WinD)。写在前面我日常使用macOS和Ubuntu来学习和工作,但是时不时会有Windows使用的场景,不论是运行某个指定的软件,还是要做一些跨平台软件的功能验证。在去年开源 soulteary/docker-chatgp......