[UOJ#404][CTSC2018]组合数问题(79分,提交答案题,模拟退火+匈牙利+DP)
1、4、5、6、10都是op=1的点,除4外直接通过模拟退火调参可以全部通过。
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
using namespace std; const int N=;
int n,m,K,op,ans,u,v,t[N][N],r[N][N],pos[N];
struct E{ int u,v; }e[N]; int sj(int l,int r){ return rand()%(r-l+)+l; }
double Rand(){ return sj(,)/.; } int calc(){
int res=;
rep(i,,n) res+=t[i][pos[i]];
rep(i,,m) res+=r[pos[e[i].u]][pos[e[i].v]];
return res;
} void SA(){
for (double T=1e30; T>0.001; T*=0.99997){
int p=sj(,n),q=sj(,K),ans1=ans-t[p][pos[p]]+t[p][q];
rep(i,,m){
if (e[i].u==p) ans1=ans1-r[pos[p]][pos[e[i].v]]+r[q][pos[e[i].v]];
if (e[i].v==p) ans1=ans1-r[pos[e[i].u]][pos[p]]+r[pos[e[i].u]][q];
}
int delta=ans-ans1;
if (delta> || Rand()<exp(delta/T)) ans=ans1,pos[p]=q;
}
rep(i,,){
int p=sj(,n),q=sj(,K),ans1=ans-t[p][pos[p]]+t[p][q];
rep(i,,m){
if (e[i].u==p) ans1=ans1-r[pos[p]][pos[e[i].v]]+r[q][pos[e[i].v]];
if (e[i].v==p) ans1=ans1-r[pos[e[i].u]][pos[p]]+r[pos[e[i].u]][q];
}
if (ans>ans1) ans=ans1,pos[p]=q;
}
} int main(){
freopen("placement5.in","r",stdin);
freopen("placement5.out","w",stdout);
srand(time());
scanf("%d%d%d%d",&n,&m,&K,&op);
rep(i,,m) scanf("%d%d",&u,&v),e[i]=(E){u,v};
rep(i,,n) rep(j,,K) scanf("%d",&t[i][j]);
rep(i,,K) rep(j,,K) scanf("%d",&r[i][j]);
rep(i,,n) pos[i]=; ans=calc(); SA();
rep(i,,n) printf("%d ",pos[i]); puts("");
return ;
}
4号点是[1,133],[134,266],[267,399]三条链,做三次同样的DP即可。
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
using namespace std; const int N=,inf=1e9;
int n,m,K,op,ans,id,u,v,t[N][N],r[N][N],pre[N][N],f[N][N]; void Print(int l,int i,int j){ if (i>l) Print(l,i-,pre[i][j]); printf("%d ",j); } int main(){
freopen("placement4.in","r",stdin);
freopen("placement4.out","w",stdout);
srand(time());
scanf("%d%d%d%d",&n,&m,&K,&op);
rep(i,,m) scanf("%d%d",&u,&v);
rep(i,,n) rep(j,,K) scanf("%d",&t[i][j]);
rep(i,,K) rep(j,,K) scanf("%d",&r[i][j]);
rep(i,,n) rep(j,,K) f[i][j]=inf;
rep(i,,) rep(j,,K)
rep(k,,K){
int s=f[i-][k]+r[k][j]+t[i][j];
if (s<f[i][j]) f[i][j]=s,pre[i][j]=k;
}
ans=inf;
rep(i,,K) if (f[][i]<ans) ans=f[][i],id=i;
Print(,,id);
rep(i,,K) f[][i]=t[][i];
rep(i,,) rep(j,,K)
rep(k,,K){
int s=f[i-][k]+r[k][j]+t[i][j];
if (s<f[i][j]) f[i][j]=s,pre[i][j]=k;
}
ans=inf;
rep(i,,K) if (f[][i]<ans) ans=f[][i],id=i;
Print(,,id);
rep(i,,K) f[][i]=t[][i];
rep(i,,) rep(j,,K)
rep(k,,K){
int s=f[i-][k]+r[k][j]+t[i][j];
if (s<f[i][j]) f[i][j]=s,pre[i][j]=k;
}
ans=inf;
rep(i,,K) if (f[][i]<ans) ans=f[][i],id=i;
Print(,,id);
return ;
}
2、3、8、9同样可以用模拟退火做,发现题目给的simulator会创建一个rex.txt来存放op=2时的答案,于是直接用它做估价函数即可。这样第二个点可以得到满分,第3个点可以得到3分,第8个点可以得到1分,第9个点可以得到5分。
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
using namespace std; const int N=;
int n,m,K,op,ans,u,v,t[N][N],r[N][N],pos[N];
struct E{ int u,v; }e[N*N]; int sj(int l,int r){ return rand()%(r-l+)+l; }
double Rand(){ return sj(,)/.; } int calc(){
freopen("placement9.out","w",stdout);
rep(i,,n) printf("%d ",pos[i]); puts("");
fclose(stdout);
system("./simulator placement9.in placement9.out");
freopen("res.txt","r",stdin);
int res; scanf("%d",&res); fclose(stdin); return res;
} void SA(){
for (double T=1e10; T>0.001; T*=0.997,cerr<<T<<endl){
int p=sj(,n),q=sj(,K),w=pos[p]; pos[p]=q;
int ans1=calc(),delta=ans-ans1;
if (delta> || Rand()<exp(delta/T)) ans=ans1; else pos[p]=w;
}
rep(i,,){
int p=sj(,n),q=sj(,K),w=pos[p]; pos[p]=q;
int ans1=calc();
if (ans>ans1) ans=ans1; else pos[p]=w;
}
} int main(){
freopen("placement9.in","r",stdin);
srand(time());
scanf("%d%d%d%d",&n,&m,&K,&op);
rep(i,,m) scanf("%d%d",&u,&v),e[i]=(E){u,v};
rep(i,,n) rep(j,,K) scanf("%d",&t[i][j]);
rep(i,,K) rep(j,,K) scanf("%d",&r[i][j]);
rep(i,,n) pos[i]=; ans=calc(); SA();
freopen("placement9.out","w",stdout);
rep(i,,n) printf("%d ",pos[i]); puts("");
return ;
}
7号点可以直接跑匈牙利得到结果。
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
using namespace std; const int N=;
int n,m,K,op,u,v,vis[N],lnk[N],ans[N],t[N][N],r[N][N],pos[N]; bool work(int x,int p){
rep(i,,K) if (t[x][i]<= && vis[i]!=p){
vis[i]=p;
if (lnk[i]==- || work(lnk[i],p)){ lnk[i]=x; return ; }
}
return ;
} int main(){
freopen("placement7.in","r",stdin);
freopen("placement7.out","w",stdout);
srand(time());
scanf("%d%d%d%d",&n,&m,&K,&op);
rep(i,,m) scanf("%d%d",&u,&v);
rep(i,,n) rep(j,,K) scanf("%d",&t[i][j]);
rep(i,,K) rep(j,,K) scanf("%d",&r[i][j]);
rep(i,,K) lnk[i]=-;
rep(i,,n) work(i,i);
rep(i,,K) if (~lnk[i]) ans[lnk[i]]=i;
rep(i,,n) printf("%d ",ans[i]);
return ;
}
[UOJ#404][CTSC2018]组合数问题(79分,提交答案题,模拟退火+匈牙利+DP)的更多相关文章
- UOJ#73. 【WC2015】未来程序 提交答案题
原文链接www.cnblogs.com/zhouzhendong/p/UOJ73.html 前言 纯属理性愉悦. 题解 Subtask1 发现就是求 $a \times b \mod c $ . 写个 ...
- uoj #190. 【集训队互测2016】消失的源代码 提交答案题
Test 1: 发现是一个字母表的映射 把 \('a' \to 'z'\) 打进去找出映射就好了QAQ . Test 2: 求助 \(dalao\) 得知的点.. 答案是 : \(2016x^2 + ...
- 【UOJ83】【UR #7】水题出题人(提交答案题)
点此看题面 大致题意: 给你若干份排序的代码,共\(6\)个子任务,每个子任务让你构造数据使得一份代码用时在给定的\(T\)以内,另一份代码用时超过\(2000000\). 子任务\(1\):归并排序 ...
- 浅谈OI中的提交答案
在OI中,题目有三类: 传统题 交互题 提交答案题 今天来了解一下第三类 概述 传统题:给你一个题面,你需要交一个程序,评测姬会用你的程序运行你看不到的一些测试点,用输出和正确答案比较 提交答案题:给 ...
- 【UOJ#275】组合数问题(卢卡斯定理,动态规划)
[UOJ#275]组合数问题(卢卡斯定理,动态规划) 题面 UOJ 题解 数据范围很大,并且涉及的是求值,没法用矩阵乘法考虑. 发现\(k\)的限制是,\(k\)是一个质数,那么在大组合数模小质数的情 ...
- 初次stack-overflow 提交答案
初次在stack-overflow上面提交答案,首先编辑器非常好用,语法检查都有, 还有付费版的,更高级,更好用,nice. 付费版:https://www.grammarly.com/upgrade ...
- LOJ2557 CTSC2018组合数问题(提交答案)
直接利用simulator退火应该可以得到大量分数. op=1:1,4,5,6,10 即构造序列{ai},最小化Σti,ai+rai,aj. 1:暴搜/退火. 4:观察到图大致成一条链(注意其中有两个 ...
- uoj #118. 【UR #8】赴京赶考 水题
#118. [UR #8]赴京赶考 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://uoj.ac/problem/118 Description ...
- poj 1430 Binary Stirling Number 求斯特林数奇偶性 数形结合| 斯特林数奇偶性与组合数的关系+lucas定理 好题
题目大意 求子集斯特林数\(\left\{\begin{matrix}n\\m\end{matrix}\right\}\%2\) 方法1 数形结合 推荐一篇超棒的博客by Sdchr 就是根据斯特林的 ...
随机推荐
- dubbo线程模型配置
首先了解一下dubbo线程模型 如果事件处理的逻辑能迅速完成,并且不会发起新的IO请求,比如只是在内存中记个标识.则直接在IO线程上处理更快,因为减少了线程池调度. 但如果事件处理逻辑较慢,或者需要发 ...
- 001 安装mysql
在安装docker之后,安装一个mysql的容器试试手.可以参考违章: URL: https://www.cnblogs.com/limingxie/p/8655457.html
- 小D课堂 - 零基础入门SpringBoot2.X到实战_第4节 Springboot2.0单元测试进阶实战和自定义异常处理_17、SpringBootTest单元测试实战
笔记 1.@SpringBootTest单元测试实战 简介:讲解SpringBoot的单元测试 1.引入相关依赖 <!--springboot程 ...
- Vscode 调试 Flutter 项目
1.Vscode 中打开 flutter 项目进行开发 2.运行 Flutter 项目 flutter run r 键:点击后热加载,也就算是重新加载吧. p 键:显示网格,这个可以很好的掌握布局情况 ...
- openresty开发系列19--lua的table操作
openresty开发系列19--lua的table操作 Lua中table内部实际采用哈希表和数组分别保存键值对.普通值:下标从1开始 不推荐混合使用这两种赋值方式. local color={fi ...
- sorry, unimplemented: non-trivial designated initializers not supported
将C语言转换为C++代码时,发生如下错误 sorry, unimplemented: non-trivial designated initializers not supported. 查找原因,是 ...
- Composer三步曲:安装、使用、发布
转载地址:https://segmentfault.com/a/1190000011858458 原文是在我自己博客中,小伙伴也可以点阅读原文进行跳转查看,还有好听的背景音乐噢~ 在现代化的PHP开发 ...
- python多线程中join()的理解
在 Python 的多线程编程中,经常碰到 thread.join()这样的代码.那么今天咱们用实际代码来解释一下 join 函数的作用. 第一,当一个进程启动之后,会默认产生一个主线程,因为线程是程 ...
- easyUIDataGrid对象返回值
import java.util.List; /** * easyUIDataGrid对象返回值 * <p>Title: EasyUIResult</p> * <p> ...
- Python第一阶段05
1.内置方法: 2.Json序列化: import json info = { 'name': 'sisi', } f = open("test.text", "w&qu ...