[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 就是根据斯特林的 ...
随机推荐
- pt-table-checksum校验与pt-table-sync修复数据【转】
1:下载工具包 登录网站下载相应的工具包 https://www.percona.com/downloads/percona-toolkit/LATEST/ 2:安装 (1)yum安装: sudo y ...
- python : 设计模式之外观模式(Facade Pattern)
#为啥要用外观模式举例说明 这个例子很形象,直接从人家博客上贴过来的,参考链接在下面 不知道大家有没有比较过自己泡茶和去茶馆喝茶的区别,如果是自己泡茶需要自行准备茶叶.茶具和开水,如图1(A)所示,而 ...
- 【转】分享一款颜色神器ColorSchemer Studio
原文:https://www.cnblogs.com/xyfll7/p/7569078.html ColorSchemer Studio是一款专业配色软件,网页设计或平面设计师必备工具,和ColorP ...
- CRM 公海 回收规则 AI
7.3.2 客户和公海管理 · 纷享销客产品手册 https://www.fxiaoke.com/mob/guide/crmdoc/src/7-3-2%E5%AE%A2%E6%88%B7%E5%92% ...
- Java基础 println 输出常量的示例
JDK :OpenJDK-11 OS :CentOS 7.6.1810 IDE :Eclipse 2019‑03 typesetting :Markdown code ...
- leetcode 293.Flip Game(lintcode 914) 、294.Flip Game II(lintcode 913)
914. Flip Game https://www.cnblogs.com/grandyang/p/5224896.html 从前到后遍历,遇到连续两个'+',就将两个加号变成'-'组成新的字符串加 ...
- Andorid-解决View重复点击的思路
Andorid-解决View重复点击的思路 转 https://www.jianshu.com/p/10d400a296fe 最近遇到一道面试题,题目是在App开发中,如何防止多次点击支付或者多次点击 ...
- python获取风和天气城市数据 ID
import requestsurl='https://cdn.heweather.com/china-city-list.csv'strhtml=requests.get(url)strhtml.e ...
- JS 数字相加出现多个小数的问题
今天在页面上用到了js进行小数相加119.01+0.01,结果大家都知道应该是:119.02的,然而结果是119..0200000…. ,莫名其妙的,还以为是我写的程序有问题,后来查了下才知道这是ja ...
- Opencv图片明暗处理
Opencv图片明暗处理 #include <iostream> #include <opencv2/opencv.hpp> using namespace std; usin ...