[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 就是根据斯特林的 ...
随机推荐
- np.vstack()和np.hstack()
本文链接:https://blog.csdn.net/m0_37393514/article/details/79538748在这里我们介绍两个拼接数组的方法: np.vstack():在竖直方向上堆 ...
- ntpd服务
yum -y install ntp 服务器端 [root@ip-172-31-6-148~]# vim /etc/ntp.conf ...# Use public servers from thep ...
- 007 搜索API
1.说明 这个API用于在elasticsearch中搜索内容,用户可以通过发送以查询字符串为参数的get请求进行搜索,也可以在post请求的消息体中进行查询. 2.多索引 允许搜索所有的索引或某些特 ...
- Git - 高级合并
Git - 高级合并https://git-scm.com/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E9%AB%98%E7%BA%A7%E5%90%88%E5%B9%B6 ...
- 【转载】 clusterdata-2011-2 谷歌集群数据分析(二)--task_usage
原文地址: https://blog.csdn.net/yangss123/article/details/78298749 由于原文声明其原创文章不得允许不可转载,故这里没有转载其正文内容. --- ...
- ISO/IEC 9899:2011 条款6.8.3——表达式与空语句
6.8.3 表达式与空语句 语法 1.expression-statement: expressionopt ; 语义 2.在一条表达式语句中的表达式被计算为一个void表达式作为其副作用.[注 ...
- OMPL 在windows下的安装
博客参考:https://blog.csdn.net/shitanding/article/details/82562702 和 https://bitbucket.org/ompl/omplapp/ ...
- 使用ffmpeg.exe进行转码参数说明
使用ffmpeg.exe进行转码参数说明 摘自:https://blog.csdn.net/coloriy/article/details/47337641 2015年08月07日 13:04:32 ...
- 【432】COMP9024,Exercise9
eulerianCycle.c What determines whether a graph is Eulerian or not? Write a C program that reads a g ...
- didMoveToSuperview方法认识和使用
由来: 今天给项目添加新功能——点击弹出阳历,阴历日期选择. 弹出日期选择是弹出的控制器,里面的日期选择控件是封装的View,View使用Xib画的, 遇到的问题是:控制器传数据给View,在awak ...