LOJ 2557 「CTSC2018」组合数问题 (46分)
题目:https://loj.ac/problem/2557
第一个点可以暴搜。
第三个点无依赖关系,k=3,可以 DP 。dp[ cr ][ i ][ j ] 表示前 cr 个任务、第一台机器最晚完成时间是 i 、第二台机器最晚完成时间是 j ,第三台机器最晚完成时间是多少。数组开 500 就行了。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int Mx(int a,int b){return a>b?a:b;}
int Mn(int a,int b){return a<b?a:b;}
const int N=,M=,K=,INF=1e9+;
int n,m,k,op,dp[N][M][M],pr[N][M][M][];
int t[N][K],r[K][K],prn[N];
int main()
{
scanf("%d%d%d%d",&n,&m,&k,&op);
for(int i=;i<=n;i++)
for(int j=;j<=k;j++)
scanf("%d",&t[i][j]);
for(int i=;i<=k;i++)
for(int j=;j<=k;j++)
scanf("%d",&r[i][j]);
memset(dp,0x3f,sizeof dp);
dp[][][]=;
for(int cr=;cr<=n;cr++)
for(int i=;i<=;i++)
for(int j=;j<=;j++)
{
int w=t[cr][];
dp[cr][i][j]=dp[cr-][i][j]+w;
pr[cr][i][j][]=i; pr[cr][i][j][]=j;
w=t[cr][];
if(i>=w&&dp[cr-][i-w][j]<dp[cr][i][j])
{
dp[cr][i][j]=dp[cr-][i-w][j];
pr[cr][i][j][]=i-w; pr[cr][i][j][]=j;
}
w=t[cr][];
if(j>=w&&dp[cr-][i][j-w]<dp[cr][i][j])
{
dp[cr][i][j]=dp[cr-][i][j-w];
pr[cr][i][j][]=i; pr[cr][i][j][]=j-w;
}
}
int ans=INF,r0,r1;
for(int i=;i<=;i++)
for(int j=;j<=;j++)
{
int d=Mx(Mx(i,j),dp[n][i][j]);
if(d<ans)ans=d,r0=i,r1=j;
}
for(int i=n;i;i--)
{
int t0=pr[i][r0][r1][],t1=pr[i][r0][r1][];
if(t0!=r0)prn[i]=; else if(t1!=r1)prn[i]=; else prn[i]=;
r0=t0; r1=t1;
}
for(int i=;i<=n;i++)printf("%d ",prn[i]);puts("");
return ;
}
第四个点连成三条编号有序的链 。 dp[ i ][ j ] 表示前 i 个任务、此刻在 j 点,最小时间总和。链断开的位置不用算“传输时间”即可。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
const int N=,K=,INF=1e9+;
int n,m,k,op,a[N],prn[N];
int t[N][K],r[K][K],dp[N][K],pr[N][K];
bool vis[N];
int main()
{
scanf("%d%d%d%d",&n,&m,&k,&op);
for(int i=,u,v;i<=m;i++)
scanf("%d%d",&u,&v);
for(int i=;i<=n;i++)
for(int j=;j<=k;j++)
scanf("%d",&t[i][j]);
for(int i=;i<=k;i++)
for(int j=;j<=k;j++)
scanf("%d",&r[i][j]);
for(int j=;j<=k;j++)
dp[][j]=t[][j];
for(int i=;i<=n;i++)
{
if(i==||i==)
{
int rt=;
for(int l=;l<=k;l++)
if(dp[i-][l]<dp[i-][rt])rt=l;
for(int j=;j<=k;j++)
{
dp[i][j]=t[i][j]+dp[i-][rt];
pr[i][j]=rt;
}
continue;
}
for(int j=;j<=k;j++)
{
dp[i][j]=INF;
for(int l=;l<=k;l++)
if(dp[i-][l]+r[l][j]<dp[i][j])
{
dp[i][j]=dp[i-][l]+r[l][j];
pr[i][j]=l;
}
dp[i][j]+=t[i][j];
}
}
int ans=;
for(int j=;j<=k;j++)if(dp[n][j]<dp[n][ans])ans=j;
for(int i=n;i;i--)
prn[i]=ans,ans=pr[i][ans];
for(int i=;i<=n;i++)printf("%d ",prn[i]);puts("");
return ;
}
第七个点,发现每个任务在每个机器上的时间差不多,所以(看别人博客)发现方案应该是二分图匹配。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return fx?ret:-ret;
}
const int N=,K=,M=N*K;
int n,m,k,op,lm=,hd[N],xnt,to[M],nxt[M],per[K],prn[N];
int t[N][K],r[K][K]; bool vis[K];
void add(int x,int y){to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;}
bool xyl(int cr)
{
for(int i=hd[cr],v;i;i=nxt[i])
if(!vis[v=to[i]])
{
vis[v]=;
if(!per[v]||xyl(per[v]))
{ per[v]=cr; return true;}
}
return false;
}
int main()
{
n=rdn();m=rdn();k=rdn();op=rdn();
for(int i=;i<=n;i++)
for(int j=;j<=k;j++) t[i][j]=rdn();
for(int i=;i<=k;i++)
for(int j=;j<=k;j++) r[i][j]=rdn();
for(int i=;i<=n;i++)
for(int j=;j<=k;j++)
if(t[i][j]<=lm)add(i,j);
for(int i=;i<=n;i++)
{
memset(vis,,sizeof vis);
xyl(i);
}
for(int i=;i<=k;i++)
if(per[i])prn[per[i]]=i;
for(int i=;i<=n;i++)printf("%d ",prn[i]);puts("");
return ;
}
剩下 op=1 的点,试图用模拟退火,但效果很不好,几乎没有什么改变。自己不是很了解随机化算法……
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<ctime>
#include<cmath>
#define db double
#define ll long long
using namespace std;
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return fx?ret:-ret;
}
int Mx(int a,int b){return a>b?a:b;}
int Mn(int a,int b){return a<b?a:b;}
const int N=,M=,K=;
const db dec=0.988,eps=1e-;
int n,m,k,op,prn[N],a[N],b[N];
int t[N][K],r[K][K],ans;
struct Ed{
int x,y;
}ed[M];
int cal(bool fx)
{
int ret=;
for(int i=;i<=n;i++)
ret+=t[i][fx?b[i]:a[i]];
for(int i=;i<=m;i++)
{
int u=ed[i].x,v=ed[i].y;
ret+=t[fx?b[u]:a[u]][fx?b[v]:a[v]];
}
return ret;
}
int get_rd(db T)
{
ll ret=(rand()*-RAND_MAX)*T;
return ret%k;
}
void SA(db T)
{
int ys=cal(),ts; int deb=;
while(T>eps)
{
int p=rand()%n+,d=a[p]+get_rd(T), cnt=;
while(d==a[p]&&cnt<)d=a[p]+get_rd(T),cnt++;
d=Mx(d,); d=Mn(d,k); b[p]=d;
ts=cal();
if(ts<ys||exp((ts-ys)/T)*RAND_MAX<rand())
{
a[p]=d; ys=ts;
if(ts<ans)memcpy(prn,a,sizeof a);
}
b[p]=a[p]; T*=dec;
}
}
int main()
{
srand(time());
n=rdn();m=rdn();k=rdn();op=rdn();
for(int i=;i<=m;i++)
{ ed[i].x=rdn();ed[i].y=rdn();}
for(int i=;i<=n;i++)
for(int j=;j<=k;j++) t[i][j]=rdn();
for(int i=;i<=k;i++)
for(int j=;j<=k;j++) r[i][j]=rdn();
for(int i=;i<=n;i++)a[i]=b[i]=prn[i]=rand()%k+;
ans=cal();
for(int i=;i<=;i++)
SA();
for(int i=;i<=n;i++)printf("%d ",prn[i]);puts("");
return ;
}
LOJ 2557 「CTSC2018」组合数问题 (46分)的更多相关文章
- LOJ2557. 「CTSC2018」组合数问题
LOJ2557. 「CTSC2018」组合数问题 这道题是我第一道自己做完的题答题.考场上面我只拿了41分,完全没有经验.现在才发现其实掌握了大概的思路还是不难. 首先模拟退火,通过了1,2,6,9, ...
- loj#2552. 「CTSC2018」假面
题目链接 loj#2552. 「CTSC2018」假面 题解 本题严谨的证明了我菜的本质 对于砍人的操作好做找龙哥就好了,blood很少,每次暴力维护一下 对于操作1 设\(a_i\)为第i个人存活的 ...
- Loj #2554. 「CTSC2018」青蕈领主
Loj #2554. 「CTSC2018」青蕈领主 题目描述 "也许,我的生命也已经如同风中残烛了吧."小绿如是说. 小绿同学因为微积分这门课,对"连续"这一概 ...
- Loj #2553. 「CTSC2018」暴力写挂
Loj #2553. 「CTSC2018」暴力写挂 题目描述 temporaryDO 是一个很菜的 OIer .在 4 月,他在省队选拔赛的考场上见到了<林克卡特树>一题,其中 \(k = ...
- loj #2143. 「SHOI2017」组合数问题
#2143. 「SHOI2017」组合数问题 题目描述 组合数 Cnm\mathrm{C}_n^mCnm 表示的是从 nnn 个互不相同的物品中选出 mmm 个物品的方案数.举个例子, 从 ...
- LOJ 2553 「CTSC2018」暴力写挂——边分治+虚树
题目:https://loj.ac/problem/2553 第一棵树上的贡献就是链并,转化成 ( dep[ x ] + dep[ y ] + dis( x, y ) ) / 2 ,就可以在第一棵树上 ...
- LOJ 2555 「CTSC2018」混合果汁——主席树
题目:https://loj.ac/problem/2555 二分答案,在可以选的果汁中,从价格最小的开始选. 按价格排序,每次可以选的就是一个前缀.对序列建主席树,以价格为角标,维护体积和.体积*价 ...
- LOJ 2554 「CTSC2018」青蕈领主——结论(思路)+分治FFT
题目:https://loj.ac/problem/2554 一个“连续”的区间必然是一个排列.所有 r 不同的.len 最长的“连续”区间只有包含.相离,不会相交,不然整个是一个“连续”区间. 只有 ...
- LOJ 2552 「CTSC2018」假面——DP
题目:https://loj.ac/problem/2552 70 分就是 f[i][j] 表示第 i 个人血量为 j 的概率.这部分是 O( n*Q ) 的:g[i][j][0/1] 表示询问的人中 ...
随机推荐
- PHP批量生成底部带编号二维码(二维码生成+文字生成图片+图片拼接合并)
PHP批量生成带底部编号二维码(二维码生成+文字生成图片+图片拼接合并) 需求: 输入编号如 : cb05-0000001 至 cb05-0000500 批量生成 以编号为名称的下图二维码,然后压缩 ...
- Using Tensorflow SavedModel Format to Save and Do Predictions
We are now trying to deploy our Deep Learning model onto Google Cloud. It is required to use Google ...
- java 工厂模式 从无到有-到简单工厂模式-到工厂方法模式-抽象工厂模式
工厂模式定义(百度百科): 工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式.著名的Jive论坛 ,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见.因为工 ...
- Interface-接口的实现与注意事项
package cn.learn.Interface; public interface MyInterfaceA { public abstract void methodA(); public a ...
- [BZOJ3622] 已经没有什么好害怕的了(dp+容斥)
Description: 有两个数组a和b,两两配对,求 \(a_i>b_i\) 的配对比 \(b_i>a_i\) 的配对多 \(k\) 个的方案数 \(k\le n\le 2000\ ...
- Notepad++添加插件Funtion List 支持PHP
插件下载地址:functionlist插件 配置方法:关闭notepad++; functionlist.dll拷贝到 安装目录/plugins目录下; 下载php.bmp 地址:https://gi ...
- JavaScript给动态插入的元素添加事件绑定
由于实际的需要,有时需要往网页中动态的插入HTML内容,并在插入的节点中绑定事件处理函数.我们知道,用Javascript向HTML文档中 插入内容,有两种方法, 一种是在写HTML代码写入JS,然后 ...
- python 从csv文件插入mysql数据库
一个工作遇到的问题,将excel文件的内容插入到mysql数据库中. 总体思路是 excel文件-->转换成csv文件-->csv文件读取-->读取数据插入mysql数据库 用到py ...
- MySQL语句优化方法(简单版)
基础回顾: sql语句是怎么样运行的? 一般来说,客户端发送sql语句到数据库服务器——数据库服务器进行运算并返回结果——客户端显示sql语句运行结果. 在本地运行时以workbench为例,客户端为 ...
- 三 Bash Shell 结构
Bash Shell 程序结构主要有 : 变量设定 内置命令 Shell 语法结构 函数 其他命令行程序构成 例子: [root@localhost ~]# vim test.sh #!/bin/b ...