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是 ...
随机推荐
- Python中的sys.stdin和input、sys.stdout与print--附带讲解剑指offer42-连续子数组的最大和
2020秋招季,终于开始刷第一套真题了,整套试卷就一道编程题,还是剑指offer上的原题,结果答案死活不对,最后干脆直接提交答案算了,看了下别人的答案,原来是输入数据没有获取的原因,不过这个语法sys ...
- JS最简单的定时累加计数器
js代码: 1 var timer , k = 0; 2 function star() { 3 k += 1; 4 document.getElementById("num"). ...
- python png图片生成gif
有时候写代码就是这样别人把代码写好你在后面加一个句号就行了 我很懒不想写成函数,你自己来吧.有注释就不错了 这个依赖一个图像处理库pillow,轮子就是轮他不是车 import imageio imp ...
- [技术博客] BeautifulSoup4分析网页
[技术博客] BeautifulSoup4分析网页 使用BeautifulSoup4进行网页文本分析 前言 进行网络爬虫时我们需要从网页源代码中提取自己所需要的信息,分析整理后存入数据库中. 在pyt ...
- CentOS系统优化一键配置脚本
#!/usr/bin/env bash PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export P ...
- HZOI帝国2019欢乐时刻
前言: update 只是恢复一下原来手残删掉的博客,不是在水,嘤嘤嘤 update 以后改成Stack,但是之前的就懒得改了... by 10.31 为了窝的访问量大家的好心情,模仿学长搞了一个这个 ...
- 震惊,hzoi的考试竟然折磨简单,活到爆!
众所周知,hzoi的考试题非常"简单",那么究竟有多简单呢?最近,一位外国小哥开发出了hzoi的考试竟然折磨简单,活到爆!的方法,这究竟是怎么一回事呢?快和小编一起来看看吧- 满分 ...
- matlab添加永久路径
addpath('D:\MATLAB6p5\toolbox\svm'); 临时添加路径,不能添加子目录 addpath(genpath('D:\MATLAB6p5\toolbox\svm'));临时添 ...
- 必备的60个常用的Linux命令
Linux必学的60个命令Linux提供了大量的命令,利用它可以有效地完成大量的工 作,如磁盘操作.文件存取.目录操作.进程管理.文件权限设定等.所以,在Linux系统上工作离不开使用系统提供的命令. ...
- Balance的数学思想构造辅助函数
本类题的证明难点便在于如何构造出满足答案的辅助函数.通过下列类题便可以很好的理解. 题一 该类题可以理解为积分内部f(x)与xf(x)处于一种失衡状态,故我们需要使其平衡,否则直接构造出的函数无法满足 ...