Codeforces 1290F - Making Shapes(数位 dp)
数位 dp 好题。
首先,由于是凸包,一但向量集合确定,凸包的形态肯定就已经确定了。考虑什么样的向量集合能够组成符合条件的凸包,我们假设第 \(i\) 个向量选了 \(c_i\) 次。因为凸包是首尾相连的,所以必然有 \(\sum\limits_{i=1}^nc_ix_i=0,\sum\limits_{i=1}^nc_iy_i=0\)。上式也可写作 \(\sum\limits_{x_i>0}c_ix_i=\sum\limits_{x_i<0}c_i(-x_i),\sum\limits_{y_i>0}c_iy_i=\sum\limits_{y_i<0}c_i(-y_i)\)。其次,由于凸包能够被放到 \(m\times m\) 的矩形内,所以凸包横纵坐标的极差必须 \(\le m\),以横坐标为例,还是因为原图是一个凸包,所以凸包的横坐标肯定是先涨一段,再跌到最低点,再涨到 \(0\),因此横坐标的极差为 \(\sum\limits_{x_i<0}c_i(-x_i)\),同理纵坐标的极差为 \(\sum\limits_{y_i<0}c_i(-y_i)\),因此一组 \(\{c_1,c_2,\cdots,c_n\}\) 符合条件的充要条件是:
- \(\sum\limits_{x_i>0}c_ix_i=\sum\limits_{x_i<0}c_i(-x_i),\sum\limits_{y_i>0}c_iy_i=\sum\limits_{y_i<0}c_i(-y_i)\)
- \(\sum\limits_{x_i<0}c_i(-x_i)\le m,\sum\limits_{y_i<0}c_i(-y_i)\le m\)
接下来思考怎样求符合条件的 \(\{c_1,c_2,\cdots,c_n\}\) 的个数。注意到 \(n\) 很小,值域也很小,因此考虑数位 DP,考虑从低到高逐位确定 \(c_i\) 每一位的值,记 \(dp_{d,px,py,nx,ny,p,q}\) 表示当前确定了最低的 \(d\) 位,当前为正的 \(x_i\) 的 \(\sum c_ix_i\) 产生了 \(px\) 的进位,当前为负的 \(x_i\) 的 \(\sum c_i(-x_i)\) 产生了 \(nx\) 的进位,当前为正的 \(y_i\) 的 \(\sum c_iy_i\) 产生了 \(py\) 的进位,当前为负的 \(x_i\) 的 \(\sum c_i(-y_i)\) 产生了 \(ny\) 的进位,当前 \(\sum\limits_{x_i>0} c_ix_i\) 的后 \(d\) 位是否 \(\le m\) 的后 \(d\) 位,当前 \(\sum\limits_{y_i>0} c_iy_i\) 的后 \(d\) 位是否 \(\le m\) 的后 \(d\) 位的符合条件的 \(\{c_i\}\) 的个数,转移就枚举这 \(n\) 个数第 \(d+1\) 位的值即可。
复杂度 \(20^4·2^5·\log m\),可以通过。写成记忆化搜索的形式可能会跑得快一点。
总结:看到求 \(\sum\limits_{i=1}^na_ic_i=X\) 的 \(\{c_i\}\) 的组数,并且 \(n,a_i\) 都很小而 \(X\) 很大的题目可以想到数位 DP,类似的还有这个题。
const int MOD=998244353;
int n,m,x[7],y[7],dp[34][23][23][23][23][2][2];
void add(int &x,int v){((x+=v)>=MOD)&&(x-=MOD);}
int chk(int dm,int dn,int ori){
if(dm^dn) return (dn<dm)?0:1;
return ori;
}
int calc(int p,int ps_x,int ps_y,int ng_x,int ng_y,int xm,int ym){
if(p==30) return (!ps_x&&!ps_y&&!ng_x&&!ng_y&&!xm&&!ym);
if(~dp[p][ps_x][ps_y][ng_x][ng_y][xm][ym]) return dp[p][ps_x][ps_y][ng_x][ng_y][xm][ym];
int d=m>>p&1;dp[p][ps_x][ps_y][ng_x][ng_y][xm][ym]=0;
for(int s=0;s<(1<<n);s++){
int tps_x=ps_x,tps_y=ps_y,tng_x=ng_x,tng_y=ng_y;
for(int i=1;i<=n;i++) if(s>>(i-1)&1){
(x[i]>0)?(tps_x+=x[i]):(tng_x-=x[i]);
(y[i]>0)?(tps_y+=y[i]):(tng_y-=y[i]);
} int d_px=tps_x&1,d_py=tps_y&1,d_nx=tng_x&1,d_ny=tng_y&1;
if(d_px==d_nx&&d_py==d_ny)
add(dp[p][ps_x][ps_y][ng_x][ng_y][xm][ym],
calc(p+1,tps_x>>1,tps_y>>1,tng_x>>1,tng_y>>1,chk(d,d_px,xm),chk(d,d_py,ym)));
} return dp[p][ps_x][ps_y][ng_x][ng_y][xm][ym];
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]);
memset(dp,-1,sizeof(dp));
printf("%d\n",(calc(0,0,0,0,0,0,0)-1+MOD)%MOD);
return 0;
}
Codeforces 1290F - Making Shapes(数位 dp)的更多相关文章
- codeforces 55D - Beautiful numbers(数位DP+离散化)
D. Beautiful numbers time limit per test 4 seconds memory limit per test 256 megabytes input standar ...
- Codeforces Gym 100231L Intervals 数位DP
Intervals 题目连接: http://codeforces.com/gym/100231/attachments Description Start with an integer, N0, ...
- Codeforces #55D-Beautiful numbers (数位dp)
D. Beautiful numbers time limit per test 4 seconds memory limit per test 256 megabytes input standar ...
- Codeforces - 55D Beautiful numbers (数位dp+数论)
题意:求[L,R](1<=L<=R<=9e18)区间中所有能被自己数位上的非零数整除的数的个数 分析:丛数据量可以分析出是用数位dp求解,区间个数可以转化为sum(R)-sum(L- ...
- CodeForces - 55D - Beautiful numbers(数位DP,离散化)
链接: https://vjudge.net/problem/CodeForces-55D 题意: Volodya is an odd boy and his taste is strange as ...
- CodeForces 628D Magic Numbers (数位dp)
题意:找到[a, b]符合下列要求的数的个数. 1.该数字能被m整除 2.该数字奇数位全不为d,偶数位全为d 分析: 1.dp[当前的位数][截止到当前位所形成的数对m取余的结果][当前数位上的数字是 ...
- FZU2179/Codeforces 55D beautiful number 数位DP
题目大意: 求 1(m)到n直接有多少个数字x满足 x可以整出这个数字的每一位上的数字 思路: 整除每一位.只需要整除每一位的lcm即可 但是数字太大,dp状态怎么表示呢 发现 1~9的LCM 是2 ...
- Codeforces 981 D.Bookshelves(数位DP)
Codeforces 981 D.Bookshelves 题目大意: 给n个数,将这n个数分为k段,(n,k<=50)分别对每一段求和,再将每个求和的结果做与运算(&).求最终结果的最大 ...
- codeforces 55D. Beautiful numbers 数位dp
题目链接 一个数, 他的所有位上的数都可以被这个数整除, 求出范围内满足条件的数的个数. dp[i][j][k], i表示第i位, j表示前几位的lcm是几, k表示这个数mod2520, 2520是 ...
随机推荐
- 你知道什么是JUC了吗?
多线程一直Java开发中的难点,也是面试中的常客,趁着还有时间,打算巩固一下JUC方面知识,我想机会随处可见,但始终都是留给有准备的人的,希望我们都能加油!!! 沉下去,再浮上来,我想我们会变的不一样 ...
- 【Linux命令063】Linux非常简单常用的入门命令
Linux常用命令 这是一篇我在公众号上发布的文章,还算较为受欢迎. 博客园这边荒废好长时间了,主要是最近一年经常撰写的文章都是Linux相关的入门文章. 不知道是否能通过博客园的首页审核. 1.cd ...
- [暴力题解&&考试反思] 双十一欢乐赛(联赛膜你测试32)
前言: 今天考试很迷糊.从7点考到11点半,我大概从7点睡到9点.隐隐约约看到旁边的狗哥敲了好几个题,我才开始写代码.然后因为还是很困,而且T1迷迷糊糊调了好长时间,T3T4的暴力就懒的写了... 估 ...
- IDEA插件开发,我是如何把公司的发布系统搬到IDEA里的
不得不说JetBrains公司直的非常的牛B,每一个程序员都能在JetBrains的官方网站找到一款属于自己的开发工具.这些开发工具在工作中给我们带来了巨大的便利.各种各样的基础插件,第三方插件,真是 ...
- 深入理解和运用Pandas的GroupBy机制——理解篇
GroupBy是Pandas提供的强大的数据聚合处理机制,可以对大量级的多维数据进行透视,同时GroupBy还提供强大的apply函数,使得在多维数据中应用复杂函数得到复杂结果成为可能(这也是个人认为 ...
- linux命令中find, which、whereis、locate,有什么区别?
whatis 用于查询一个命令执行什么功能,并将查询结果打印到终端上 which 查看可执行文件的位置 whereis 查看文件的位置 man Linux提供了丰富的帮助手册,当你需要查看某个命令的参 ...
- 求1+2+3...+n 牛客网 剑指Offer
求1+2+3...+n 牛客网 剑指Offer 题目描述 求1+2+3+...+n,要求不能使用乘除法.for.while.if.else.switch.case等关键字及条件判断语句(A?B:C). ...
- insertion-sort-list leetcode C++
Sort a linked list using insertion sort. C++ /** * Definition for singly-linked list. * struct ListN ...
- hdu 2159 FATE(DP)
题意: 小余玩游戏,离最后一级还需n的经验值,但是他已经很厌烦了,还剩下m的忍耐度.每杀一只怪小余会得到相应的经验,同时减掉相应的忍耐度. 当忍耐度降到0或者0以下时,小余就不会再玩这个游戏.小余还说 ...
- spring-cloud-square源码速读(spring-cloud-square-okhttp篇)
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...