题目背景

原创:b2019dy

gcd是一个热爱游戏的人

题目描述

gcd最近在玩一个有趣的游戏

我们把这个游戏抽象成一张图,图上有n个点,我们需要寻找总计m件宝物,它们分布在图上,对于每件宝物而言,将会有一个前置集合S.只有当取得所有前置宝物时,才能获得该宝物。

gcd拥有一件神器,这件神器具有传送功能,它可以使用k次,可以传送到一个任意节点。

对于游戏而言,肯定会有额外的成就,这些成就会奖励一定的传送次数,成就的达成是满足集合S的一瞬间。

现在gcd想知道能最快通关的方法

输入输出格式

输入格式:

第一行:n,m,k

第二行:s表示成就的数量

以下s行,num表示需求多少个宝物,然后num个数,为所需宝物编号

第s+3行:a1​,a2​,⋯as​表示成就的奖励次数

第s+4行:mp1​,p2​,⋯pm​表示宝物的位置

第s+5行:e表示边的总数

以下e行:每行三个数x,y,z表示x与y之间有无向边连接,边权为z.

以下m行:每行一个数num表示第i个宝物的前置要求数,之后num个数,表示所需宝物编号

最后一行:st表示起点

输出格式:

最少时间

输入输出样例

输入样例#1: 复制

3 2 0

1

1 1

1

2 3

3

1 2 20

1 3 20

3 2 1

0

0

1

输出样例#1: 复制

20

输入样例#2: 复制

3 2 0

1

1 1

1

2 3

3

1 2 1

1 3 20

3 2 20

1 2

0

1

输出样例#2: 复制

40

说明

对于20%的数据,s=0

对于100%的数据:n≤200,m≤12,k≤4,s≤8,e≤20000

奖励次数总和不超过8

数据保证每两个宝物的位置不相同

可能有重边

数据保证有解


就是状压啦

想到三维状态\(f[i][j][k]\)表示那宝藏状态为\(i\)时,传送了\(j\)次,现在在位置\(k\)时的最少步数

预处理出每个合法状态和每个合法状态可以由那些状态转移过来

似乎还是很难用dp状态转移,用记忆化搜索会比较好写


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define LL long long
#define M 1000001
#define max(a,b) ((a)>(b)? (a):(b))
#define min(a,b) ((a)<(b)? (a):(b)) using namespace std; int i,m,n,j,k,f[4099][13][13],ss,t,s[20],g,gi[20],p[10001],e,d[201][202],x,y,z,l,q[M],st,w[100001],bl[100001],r[4500][4500],ans=0x3f3f3f3f; int dp(int now,int bs,int t)
{
if(now==(1<<m)-1) ans=min(ans,f[now][bs][t]);
for(int i=1;i<=r[bl[now]][0];i++)
{
int y=0,x=0;
if(bs>=k) for(int j=1;j<=ss;j++) if((s[j] ^now)==now-s[j]) y+=gi[j];
int z=r[bl[now]][i]^now;
while(z) z>>=1,x+=1;
if(y+k>bs) if(f[r[bl[now]][i]][bs+1][x]>f[now][bs][t])
{
f[r[bl[now]][i]][bs+1][x]=f[now][bs][t];
dp(r[bl[now]][i],bs+1,x);
}
if(f[r[bl[now]][i]][bs][x]>f[now][bs][t]+d[p[t]][p[x]])
{
f[r[bl[now]][i]][bs][x]=f[now][bs][t]+d[p[t]][p[x]];
dp(r[bl[now]][i],bs,x);
}
}
} int main()
{
scanf("%d%d%d%d",&n,&m,&k,&ss);
for(i=1;i<=ss;i++)
{
scanf("%d",&t);
for(t;t;t--)
{
scanf("%d",&g);
s[i]|=1<<(g-1);
}
}
for(i=1;i<=ss;i++) scanf("%d",&gi[i]);
for(i=1;i<=m;i++) scanf("%d",&p[i]);
scanf("%d",&e);
memset(d,0x3f,sizeof(d));
for(i=1;i<=e;i++)
{
scanf("%d%d%d",&x,&y,&z);
d[y][x]=d[x][y]=min(d[x][y],z);
} for(l=1;l<=n;l++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(i!=j) d[j][i]=d[i][j]=min(d[i][l]+d[l][j],d[i][j]);
else d[i][j]=0; for(i=1;i<=m;i++)
{
scanf("%d",&t);
for(j=1;j<=t;j++)
{
scanf("%d",&g);
q[i]|=1<<(g-1);
}
} scanf("%d",&st);
for(i=1;i<1<<m;i++)
{
g=i; int b=1;
while(g)
{
int h=g & -g, x=0;
g-=h;
while(h) x+=1, h>>=1;
if(i-q[x]!=(i^q[x])) b=0;
g-=h;
}
if(b) w[++w[0]]=i, bl[i]=w[0];
} for(i=1;i<=w[0];i++)
{
t=w[i];
while(t)
{
g=t & -t;
if(bl[w[i]-g]) r[bl[w[i]-g]][++r[bl[w[i]-g]][0]]=w[i];
t-=g;
}
}
memset(f,0x3f,sizeof(f));
t=1<<(st-1), y=0;
for(j=1;j<=ss;j++) if(s[j]==t) y+=gi[j];
for(i=0;i<m;i++)
{
t=1<<i, y=0;
if(q[i+1]) continue;
f[t][0][i+1]=d[st][p[i+1]];
dp(t,0,i+1); if(k+y>=1)
{
f[t][1][i+1]=0;
dp(t,1,i+1);
}
} printf("%d",ans);
}

gcd?人生赢家!的更多相关文章

  1. Objective-C三种定时器CADisplayLink / NSTimer / GCD的使用

    OC中的三种定时器:CADisplayLink.NSTimer.GCD 我们先来看看CADiskplayLink, 点进头文件里面看看, 用注释来说明下 @interface CADisplayLin ...

  2. iOS 多线程之GCD的使用

    在iOS开发中,遇到耗时操作,我们经常用到多线程技术.Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法,只需定义想要执行的任务,然后添加到适当的调度队列 ...

  3. 【swift】BlockOperation和GCD实用代码块

    //BlockOperation // // ViewController.swift import UIKit class ViewController: UIViewController { @I ...

  4. 修改版: 小伙,多线程(GCD)看我就够了,骗你没好处!

    多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术.具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能.具有这种能力的系 ...

  5. GCD的相关函数使用

    GCD 是iOS多线程实现方案之一,非常常用 英文翻译过来就是伟大的中枢调度器,也有人戏称为是牛逼的中枢调度器 是苹果公司为多核的并行运算提出的解决方案 1.一次性函数 dispatch_once 顾 ...

  6. hdu1695 GCD(莫比乌斯反演)

    题意:求(1,b)区间和(1,d)区间里面gcd(x, y) = k的数的对数(1<=x<=b , 1<= y <= d). 知识点: 莫比乌斯反演/*12*/ 线性筛求莫比乌 ...

  7. hdu2588 GCD (欧拉函数)

    GCD 题意:输入N,M(2<=N<=1000000000, 1<=M<=N), 设1<=X<=N,求使gcd(X,N)>=M的X的个数.  (文末有题) 知 ...

  8. BZOJ 2820: YY的GCD [莫比乌斯反演]【学习笔记】

    2820: YY的GCD Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1624  Solved: 853[Submit][Status][Discu ...

  9. BZOJ 2818: Gcd [欧拉函数 质数 线性筛]【学习笔记】

    2818: Gcd Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 4436  Solved: 1957[Submit][Status][Discuss ...

随机推荐

  1. 利用SignalR来同步更新Winfrom小试

    之前写了个用Socket来更新多个Winfrom的试例,这两天看了下SignalR,也用这个来试一下 SignalR 地址:https://www.asp.net/signalr 我这个也是基于 ht ...

  2. [C语言] 数据结构-算法效率的度量方法-事前分析估算方法

    事前分析估算方法:在计算机程序编制前,依据统计方法对算法进行估算,抛开与计算机硬件软件有关的因素,一个程序的运行时间,依赖于算法的,好坏和问题的输入规模,所谓问题输入规模是指输入量的多少 推导过程,比 ...

  3. IDEA相关设置

    今天终于放弃了MyEclipse,在使用MyEclipse中的各种心酸就不多说,总结成一句话就是:珍爱生命,远离MyEclipse. 换到IDEA后,安装了IdeaVim插件,支持vim的操作,提高的 ...

  4. VS2015编译OpenSSL

    概述 OpenSSL 是一个开源的第三方库,它实现了 SSL(Secure SocketLayer)和 TLS(Transport Layer Security)协议,被广泛企业应用所采用.对于一般的 ...

  5. 解决:java 读取 resources 下面的 json 文件

    前言:java 读取 工程下的配置文件,文件类型为 json(*.json),记录一下始终读取不到 json 文件的坑.maven项目 直接上工具类代码 package com.yule.compon ...

  6. Git 小记

    感觉用github管理自己平时的一些代码挺方便的,尤其还有各种统计,作为一个码农,就有一种每日签到.累计签到统计的感觉.用github,学习git自然是不可避免的,原先只是用几个 git clone  ...

  7. 在vue中子组件修改props引发的对js深拷贝和浅拷贝的思考

    不管是react还是vue,父级组件与子组件的通信都是通过props来实现的,在vue中父组件的props遵循的是单向数据流,用官方的话说就是,父级的props的更新会向下流动到子组件中,反之则不行. ...

  8. springboot 文件上传和下载

    文件的上传和下载 1.文件上传 html页面代码如下 <form method="post" action="/file/upload1" enctype ...

  9. exception processing, template error resolving template

    错误信息:Exception processing template “/view/df”: Error resolving template “/view/df”, template might n ...

  10. JavaSE (二)

    this关键字 当一个对象创建后,Java虚拟机(JVM)就会给这个对象分配一个引用自身的指针,这个指针的名字就是 this. 用法:对当前对象的默认引用 调用自己的的构造方法. 用在构造方法内部,区 ...