题意:给定n个物品,每个物品可以取无限次,每个物品有两种属性:价值v和颜色c

现在有q个询问,每次询问是否能取出价值和为S的方案,如有多解输出不同颜色种数的最大值

题意:看到BZOJ评论区有好心人说CC上有上一题的加强版就写了一下

首先按颜色分组,每组中取或不取只有0/1

对于每组内部就是一个同余最短路

设dp[i][j][k]为当前组不取(0)/取(1),当前共有j种不同的,模意义下和为k的最小总价值

每次建图跑SPFA转移,每次询问时暴力从大到小枚举颜色种数判断是否有解

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int,int> PII;
typedef pair<ll,ll> Pll;
typedef vector<int> VI;
typedef vector<PII> VII;
typedef pair<ll,ll>P;
#define N 200010
#define M 6000010
//#define INF 1e9
#define fi first
#define se second
#define MP make_pair
#define pb push_back
#define pi acos(-1)
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
#define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
#define lowbit(x) x&(-x)
#define Rand (rand()*(1<<16)+rand())
#define id(x) ((x)<=B?(x):m-n/(x)+1)
#define ls p<<1
#define rs p<<1|1
#define fors(i) for(auto i:e[x]) if(i!=p) const int MOD=1e8+,inv2=(MOD+)/;
int p=1e4+;
double eps=1e-;
int dx[]={-,,,};
int dy[]={,,-,}; struct arr
{
int x,y;
}a[N]; bool cmp(arr a,arr b)
{
return a.y<b.y;
} struct node
{
int x,y,z;
node(){}
node(int a,int b,int c){x=a,y=b,z=c;}
}q[]; ll dis[][][N],INF;
int vis[][][N],mn,c; int read()
{
int v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} ll readll()
{
ll v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} void spfa(int now)
{
int t=,w=;
q[]=node(,,);
vis[][][]=;
rep(i,,)
rep(j,,c)
rep(k,,mn-)
if(dis[i][j][k]!=INF)
{
w++;
q[w]=node(i,j,k);
vis[i][j][k]=;
}
while(t<w)
{
t++;
int x=q[t].x,y=q[t].y,z=q[t].z;
vis[x][y][z]=;
int A=,B=y+-x,C=(z+now)%mn;
if(dis[x][y][z]+now<dis[A][B][C])
{
dis[A][B][C]=dis[x][y][z]+now;
if(!vis[A][B][C])
{
w++;
q[w]=node(A,B,C);
vis[A][B][C]=;
}
} }
} int main()
{
//freopen("1.in","r",stdin);
//freopen("1.out","w",stdout);
int n=read();
mn=1e9;
rep(i,,n) a[i].x=read(),a[i].y=read(),mn=min(mn,a[i].x);
sort(a+,a+n+,cmp);
mem(dis,0x3f);
INF=dis[][][];
c=;
dis[][][]=;
rep(i,,n-)
{
if(a[i].y!=a[i+].y)
{
rep(j,,c)
rep(k,,mn-) dis[][j][k]=min(dis[][j][k],dis[][j][k]);
}
spfa(a[i+].x);
if(a[i].y!=a[i+].y) c++;
}
rep(j,,c)
rep(k,,mn-) dis[][j][k]=min(dis[][j][k],dis[][j][k]);
int Q=read();
while(Q--)
{
ll x=readll();
int u=x%mn;
int flag=;
per(i,n,)
{
if(dis[][i][u]<=x)
{
printf("%d\n",i);
flag=;
break;
}
}
if(!flag) printf("-1\n");
}
return ;
}

【CodeChef】LECOINS(同余最短路,背包DP)的更多相关文章

  1. 【66测试20161115】【树】【DP_LIS】【SPFA】【同余最短路】【递推】【矩阵快速幂】

    还有3天,今天考试又崩了.状态还没有调整过来... 第一题:小L的二叉树 勤奋又善于思考的小L接触了信息学竞赛,开始的学习十分顺利.但是,小L对数据结构的掌握实在十分渣渣.所以,小L当时卡在了二叉树. ...

  2. 背包dp整理

    01背包 动态规划是一种高效的算法.在数学和计算机科学中,是一种将复杂问题的分成多个简单的小问题思想 ---- 分而治之.因此我们使用动态规划的时候,原问题必须是重叠的子问题.运用动态规划设计的算法比 ...

  3. hdu 5534 Partial Tree 背包DP

    Partial Tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid= ...

  4. HDU 5501 The Highest Mark 背包dp

    The Highest Mark Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?p ...

  5. Codeforces Codeforces Round #319 (Div. 2) B. Modulo Sum 背包dp

    B. Modulo Sum Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/577/problem/ ...

  6. noj [1479] How many (01背包||DP||DFS)

    http://ac.nbutoj.com/Problem/view.xhtml?id=1479 [1479] How many 时间限制: 1000 ms 内存限制: 65535 K 问题描述 The ...

  7. HDU 1011 树形背包(DP) Starship Troopers

    题目链接:  HDU 1011 树形背包(DP) Starship Troopers 题意:  地图中有一些房间, 每个房间有一定的bugs和得到brains的可能性值, 一个人带领m支军队从入口(房 ...

  8. BZOJ 1004: [HNOI2008]Cards( 置换群 + burnside引理 + 背包dp + 乘法逆元 )

    题意保证了是一个置换群. 根据burnside引理, 答案为Σc(f) / (M+1). c(f)表示置换f的不动点数, 而题目限制了颜色的数量, 所以还得满足题目, 用背包dp来计算.dp(x,i, ...

  9. G - Surf Gym - 100819S -逆向背包DP

    G - Surf Gym - 100819S 思路 :有点类似 逆向背包DP , 因为这些事件发生后是对后面的时间有影响. 所以,我们 进行逆向DP,具体 见代码实现. #include<bit ...

随机推荐

  1. RSA加密 抛异常 algid parse error, not a sequence

    JDK1.8环境 参考:BouncyCastle的使用:https://blog.csdn.net/qq_29583513/article/details/78866461 可解决 公钥解密 私钥加密 ...

  2. set的常见用法

    set的使用 set是什么 set是一个内部有序且不含重复元素的容器 用处 *使得元素自动有序 *去除重复元素 set的引入 # include <set> using namespace ...

  3. eclipse project--->clean作用

    eclipse project-->clean  ,clean主要是class文件删除,并同时编译新的工程,生成新的class文件. 如果修改代码后,在运行时,还是旧代码,可能class文件还是 ...

  4. wordpress后台编辑如何显示定义的`style.css`样式

    wordpress后台编辑如何显示定义的style.css样式 由于公司官网采用wordpress进行搭建,但是却又自己设计页面,无奈主题只能自行构建了,直接修改wordpress自带的主题进行修改. ...

  5. JavaSE--基础知识

    Java基础知识 一.基础知识 1.java命名规则 由26个英文字母大小写,0-9 ,_或 $ 组成 数字不可以开头. 不可以使用关键字和保留字,但能包含关键字和保留字. Java中严格区分大小写, ...

  6. mysql优化--explain关键字

    MySQL性能优化---EXPLAIN 参见:https://blog.csdn.net/jiadajing267/article/details/81269067 参见:https://www.cn ...

  7. C语言IOCP

    C语言的IOCP example #include <winsock2.h> #include <ws2tcpip.h> #include <mswsock.h> ...

  8. 玩转Android状态栏

    前言 前段时间,突然收到一个状态栏颜色优化设计的任务,将原本应用整体的黑色状态栏修改为根据标题栏颜色进行沉浸式设计,显示效果如下:   image 经过分析及踩过N多坑,终于完成了APP全局的修改.现 ...

  9. 2019-11-29-dotnet-core-使用-CoreRT-将程序编译为-Native-程序

    title author date CreateTime categories dotnet core 使用 CoreRT 将程序编译为 Native 程序 lindexi 2019-11-29 08 ...

  10. Java中的==和equals( )方法

    在Java中,equals和==都是用于检测两个字符串是否相等,返回类型也都是boolean值,但是二者内部处理却不一样. ==与equals( ) ==在Java中是一个二元操作符,用于比较原生类型 ...