【Luogu P1935】[国家集训队]圈地计划
题目
最近房地产商 GDOI (Group of Dumbbells Or Idiots) 从 NOI (Nuts Old Idiots) 手中得到了一块开发土地。
据了解,这块土地是一块矩形的区域,可以纵横划分为 \(N\times M\) 块小区域。GDOI 要求将这些区域分为商业区和工业区来开发。
根据不同的地形环境,每块小区域建造商业区和工业区能取得不同的经济价值。更具体点,对于第 \(i\) 行第 \(j\) 列的区域,建造商业区将得到 \(A_{ij}\) 收益,建造工业区将得到 \(B_{ij}\) 收益。
另外,不同的区域连在一起可以得到额外的收益,即如果区域\((I,j)\)相邻(相邻是指两个格子有公共边)有 \(K\) 块(显然 \(K\) 不超过 \(4\))类型不同于\((I,j)\)的区域,则这块区域能增加 \(k\times C_{ij}\) 收益。
经过 Tiger.S 教授的勘察,收益矩阵 \(A,B,C\) 都已经知道了。你能帮 GDOI 求出一个收益最大的方案么?
分析
网络流是不可能网络流的, 这辈子都不可能网络流的.
我发现有 \(2^{nm}\) 种解, 然而答案范围只有 \(1000nm\), 说明有大量的重复解, 那还写正解?
这道题我用模拟退火, 随机的是一个矩阵代表每个地方是什么区域.
每次随机一个点做一些微小的变化就可以了.
(如果调参调不下去可以试试多退火几次, 跳出局部最优)
比如我是这样写的:
int ans = 0;
for(int i = 0; i < 42; i++)
ans = std::max(SA(), ans);
printf("%d", ans);
代码
(不保证每时每刻你提交这份都能 AC)
#include <bits/stdc++.h>
const int kMaxSize = 105, mod = 1e9 + 7;
const double delta = 0.994, sup = 1e17, eps = 1e-17;
bool plan[kMaxSize][kMaxSize];
int n, m, a[kMaxSize][kMaxSize], b[kMaxSize][kMaxSize], c[kMaxSize][kMaxSize];
unsigned sed = time(NULL);
inline unsigned Rand() {
sed = ((sed * 0x3abcd1ac + 0xabc12ab2) ^ (sed + 0x1230bace)) % mod;
return sed;
}
int GetIncome() {
int ans = 0;
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++) {
if(plan[i][j]) ans += a[i][j];
else ans += b[i][j];
if(i - 1 >= 0 && plan[i - 1][j] != plan[i][j]) ans += c[i][j];
if(j - 1 >= 0 && plan[i][j - 1] != plan[i][j]) ans += c[i][j];
if(i + 1 < n && plan[i + 1][j] != plan[i][j]) ans += c[i][j];
if(j + 1 < m && plan[i][j + 1] != plan[i][j]) ans += c[i][j];
}
return ans;
}
inline int change(int ans, int x, int y) {
plan[x][y] ^= 1;
ans += plan[x][y] ? a[x][y] - b[x][y] : b[x][y] - a[x][y];
if(x - 1 >= 0) {
ans += plan[x - 1][y] != plan[x][y] ?
c[x][y] + c[x - 1][y] : -(c[x][y] + c[x - 1][y]);
}
if(y - 1 >= 0) {
ans += plan[x][y - 1] != plan[x][y] ?
c[x][y] + c[x][y - 1] : -(c[x][y] + c[x][y - 1]);
}
if(x + 1 < n) {
ans += plan[x + 1][y] != plan[x][y] ?
c[x][y] + c[x + 1][y] : -(c[x][y] + c[x + 1][y]);
}
if(y + 1 < m) {
ans += plan[x][y + 1] != plan[x][y] ?
c[x][y] + c[x][y + 1] : -(c[x][y] + c[x][y + 1]);
}
return ans;
}
int SA() {
register int ans, old_ans, new_ans, cnt = 0;
ans = old_ans = GetIncome();
for(register double T = sup; T > eps; T *= delta) {
int x = Rand() % n, y = Rand() % m;
new_ans = change(old_ans, x, y);
ans = new_ans > ans ? new_ans : ans;
if(new_ans > old_ans ||
Rand() <= exp((new_ans - old_ans) * 1.0 / T) * mod)
old_ans = new_ans;
else plan[x][y] ^= 1;
cnt++;
}
return ans;
}
int main() {
srand(time(NULL));
scanf("%d%d", &n, &m);
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
scanf("%d", &a[i][j]);
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
scanf("%d", &b[i][j]);
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
scanf("%d", &c[i][j]);
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
plan[i][j] = a[i][j] > b[i][j];
int ans = 0;
for(int i = 0; i < 42; i++)
ans = std::max(SA(), ans);
printf("%d", ans);
return 0;
}
结语
不过, Luogu的数据貌似有点水, 这个代码在一些地方貌似过不了?
【Luogu P1935】[国家集训队]圈地计划的更多相关文章
- 洛谷P1935 [国家集训队]圈地计划
题目大意: 有个\(n*m\)的网格图 每个点可以选择\(A\),获得\(A[i][j]\)或选\(B\)获得\(B[i][j]\)的收益 相邻点有\(k\)个不同可以获得\(C[i][j]\)的收益 ...
- 洛谷$P1935$ [国家集训队]圈地计划 网络流
正解:最小割 解题报告: 传送门 就文理分科模型嘛$QwQ$?所以就,跑个最小割呗,然后就做完辣?仔细想想细节发现并麻油那么简单嗷$QwQ$ 先考虑如果没有这个$k\cdot C_{i,j}$的贡献就 ...
- luogu P2757 [国家集训队]等差子序列
题目链接 luogu P2757 [国家集训队]等差子序列 题解 线段树好题 我选择暴力 代码 // luogu-judger-enable-o2 #include<cstdio> inl ...
- luogu P2619 [国家集训队2]Tree I
题目链接 luogu P2619 [国家集训队2]Tree I 题解 普通思路就不说了二分增量,生成树check 说一下坑点 二分时,若黑白边权有相同,因为权值相同优先选白边,若在最有增量时出现黑白等 ...
- [Luogu P1829] [国家集训队]Crash的数字表格 / JZPTAB (莫比乌斯反演)
题面 传送门:洛咕 Solution 调到自闭,我好菜啊 为了方便讨论,以下式子\(m>=n\) 为了方便书写,以下式子中的除号均为向下取整 我们来颓柿子吧qwq 显然,题目让我们求: \(\l ...
- Luogu P1297 [国家集训队]单选错位
P1297 [国家集训队]单选错位 题目背景 原 <网线切割>请前往P1577 题目描述 gx和lc去参加noip初赛,其中有一种题型叫单项选择题,顾名思义,只有一个选项是正确答案.试卷上 ...
- Luogu P2619 [国家集训队2]Tree I(WQS二分+最小生成树)
P2619 [国家集训队2]Tree I 题意 题目描述 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有\(need\)条白色边的生成树. 题目保证有解. 输入输出格式 输入格式 ...
- 【luogu P1494 [国家集训队]小Z的袜子】 题解
题目链接:https://www.luogu.org/problemnew/show/P1494 #include <cstdio> #include <algorithm> ...
- 【luogu P1903 [国家集训队]数颜色】 题解
题目链接:https://www.luogu.org/problemnew/show/P1903 裸的...带修莫队... 比较麻烦吧(对我来说是的) 两个变量分开记录查询和修改操作. #includ ...
随机推荐
- ACM-ICPC(9/25)
DP专题 记忆化搜索与递推(方式) DAG模型 记忆化搜索: 用d[状态] 的特殊值表示是否计算过. 用vis[状态]是否访问过 DAG模型: 矩形嵌套:d(i) 以 i 结点开始的最长长度, 存在 ...
- 【[NOI2013]矩阵游戏】
我们看到了及其可怕的数据范围 这个样子都没有办法直接读入的数据范围应该怎么算 我们观察一下递推式\(f[i][j]=a*f[i][j]+b(j!=1)\) \(f[i][1]=c*f[i-1][m]+ ...
- T-SQL 基础 2
运行结果: while 循环 运行结果: 运行结果 : if 判断语句 计算 1到100的基数 运行结果 1到100的偶数 运行结果 局部变量前缀是 @ 全局变量(包括系统变量) 前缀是 @@
- maven学习记录四——私服 nexus
8 私服 nexus 安装nexus 启动服务 启动失败的解决方法: 登录nexus 用户名/密码 admin/admin123 仓库类型 Virtual 虚拟仓库 Proxy 代 ...
- qbxt Day1 测试犯傻祭祀
今天是2018/7/15 然后又是我最不喜乱的测试,期末考试爆炸仍在眼前. T1 van♂游戏 题意 小喵喵喜欢玩RPG游戏.在这款游戏中,玩家有两个属性,攻击和防御,现在小喵喵的攻击和防御都是1,接 ...
- 【luogu P3469 [POI2008]BLO-Blockade】 题解
题目链接:https://www.luogu.org/problemnew/show/P3469 #include <cstdio> #include <cstring> #i ...
- java之递归学习
递归思想(2018-10-22): 递归就是方法里调用自身 在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口 递归算法代码显得很简洁,但递归算法解题的运行效率较低.所以不提倡用递归设计程序 ...
- iOS Xcode 小技巧,提升理解查询能力,Command + 点击鼠标右键 Jump to Definition等
前言: 介绍下Xcode 小技巧,以及一下快捷键,让你调试程序更加出类拔萃,安排! Command + 点击鼠标右键 Jump to Definition,可能你平时也在用,但是你明白全部的用法吗,试 ...
- c# TCP高性能通信
开篇都是吹牛逼哈... 我原本打算使用dotnetty来解决传输问题,但是试了下没有成功,也没有找到相关问题解决方法,导出源码,好大啊.暂时不想研究,而且是.Net Core的.最后没有办法,就自己封 ...
- 因为之前完全没有接触过Spring,所以准备先把spring实战看完再落实项目
因为之前完全没有接触过Spring,所以准备先把spring实战看完再落实项目