清北学堂模拟赛d2t6 分糖果(candy)
题目描述
总共有n颗糖果,有3个小朋友分别叫做L,Y,K。每个小朋友想拿到至少k颗糖果,但这三个小朋友有一个共同的特点:对3反感。也就是说,如果某个小朋友拿到3颗,13颗,31颗,333颗这样数量的糖果,他就会不开心。(也即它拿到的糖果数量不包含有一位是3)
LYK掌管着这n颗糖果,它想问你有多少种合理的分配方案使得将这n颗糖果全部分给小朋友且没有小朋友不开心。
例如当n=3,k=1时只有1种分配方案,当n=4,k=1时有3种分配方案分别是112,121,211。当n=7,k=2时则不存在任何一种合法的方案。
当然这个答案可能会很大,你只需输出答案对12345647取模后的结果就可以了。
输入格式(candy.in)
第一行两个数表示n,k。
输出格式(candy.out)
一个数表示方案总数。
输入样例
99999 1
输出样例
9521331
对于30%的数据n<=100
对于50%的数据n<=1000。
对于另外30%的数据k=1。
对于100%的数据3<=n<=10^10000,1<=k<=n/3,且n,k不包含前导0。
分析:对于前50%的点,直接暴力枚举+判断就可以了.后50%的点数据和前50%的点数据规模完全不是一个数量级的,肯定要用不同的算法.数字肯定不能在时间复杂度里的,肯定是对数位进行处理,那么就要用到数位dp.
这道题也不是一道特别简单的数位dp,因为要3个数的和等于n,所以我们可以在每一数位的时候枚举3个数上的这一位的值,它们的和与n的第i位相差是≤2的,因为进位最多进两位。同时还有≥k这个限制,所以我们可以设状态f[i][j][kk][l][p]表示前i位,第i+1位要向第i位进j位,kk,l,p表示枚举的3个数是否>k.每次递推的时候就能知道下一个状态,就能够就行转移了.
要求方案数,数字位数又这么多,能想到的算法只有数位dp了,从数字看向数位,是一种很好的思想的转变,如果数位dp有数字大小的限制,那么通用的办法就是加一维表示是否超出限制即可.
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std;
const int mod = ; char n[], k[];
int len1, len2,a[],b[],f[][][][][],ans; int main()
{
scanf("%s", n + );
len1 = strlen(n + );
scanf("%s", k + );
len2 = strlen(k + );
for (int i = ; i <= len1; i++)
a[i] = n[i] - '';
for (int i = ; i <= len2; i++)
b[i + len1 - len2] = k[i] - '';
f[][][][][] = ;
for (int i = ; i < len1; i++)
for (int j = ; j <= ; j++)
for (int k = ; k <= ; k++)
for (int l = ; l <= ; l++)
for (int p = ; p <= ; p++)
if (f[i][j][k][l][p])
for (int q = ; q <= ; q++)
if (q != )
for (int q2 = ; q2 <= ; q2++)
if (q2 != )
for (int q3 = ; q3 <= ; q3++)
if (q3 != )
{
int ni = i + , nj = j * + a[i + ] - q - q2 - q3;
int nk, nl, np;
if (nj < || nj > )
continue;
if (k == && q < b[ni])
continue;
nk = (k || q > b[ni]);
if (l == && q2 < b[ni])
continue;
nl = (l || q2 > b[ni]);
if (p == && q3 < b[ni])
continue;
np = (p || q3 > b[ni]);
f[ni][nj][nk][nl][np] += f[i][j][k][l][p];
if (f[ni][nj][nk][nl][np] >= mod)
f[ni][nj][nk][nl][np] -= mod;
}
for (int i = ; i <= ; i++) //为什么要枚举0?因为我们排除了<k的情况,0就是=k的情况
for (int j = ; j <= ; j++)
for (int k = ; k <= ; k++)
{
ans += f[len1][][i][j][k];
if (ans >= mod)
ans -= mod;
}
printf("%d\n", ans); return ;
}
清北学堂模拟赛d2t6 分糖果(candy)的更多相关文章
- 清北学堂模拟赛day7 数字碰撞
/* clj:水题别人都满分你不是你就完了,所以说水题一定要细心一点,有这么几个细节:①前导零的处理,全是零的时候要特判②换行要注意,不要多大一行,剩下就是水水的模拟了 */ #include< ...
- 清北学堂模拟赛d2t2 位运算2(bit)
题目描述LYK拥有一个十进制的数N.它赋予了N一个新的意义:不考虑N的符号,将N每一位都拆开来后再加起来就是N所拥有的价值.例如数字123拥有6的价值,数字999拥有27的价值,数字-233拥有8的价 ...
- 清北学堂模拟赛d1t6 或和异或(xor)
题目描述 LYK最近在研究位运算,它研究的主要有两个:or和xor.(C语言中对于|和^) 为了更好的了解这两个运算符,LYK找来了一个2^n长度的数组.它第一次先对所有相邻两个数执行or操作,得到一 ...
- 清北学堂模拟赛d1t5 拍照(photo)
题目描述 假设这是一个二次元.LYK召集了n个小伙伴一起来拍照.他们分别有自己的身高Hi和宽度Wi.为了放下这个照片并且每个小伙伴都完整的露出来,必须需要一个宽度为ΣWi,长度为max{Hi}的相框. ...
- 清北学堂模拟赛d1t3 听音乐(music)
题目描述 LYK喜欢听音乐,总共有n首音乐,有m个时刻,每个时刻LYK会听其中一首音乐,第i个时刻会听第ai首音乐.它给自己定了一个规定,就是从听音乐开始,听的每连续n首音乐都是互不相同的.例如当n= ...
- 清北学堂模拟赛d3t2 b
分析:一道比较让人头疼的数学题. 先考虑怎么让分出来的三角形相似,先不考虑每个三角形的具体边长,设每个三角形的周长为li,则可知必然有一个数g = gcd{li},每一个三角形的周长都是g的倍数,这样 ...
- 清北学堂模拟赛d4t2 b
分析:比较复杂的一题. 首先要求k个mod m互不相同且和为n的数ai,我们可以转化为求和为k个bi,并且(Σbi) % m = n % m 其中bi=ai % m,接下来可以用dp求出选了i个b,和 ...
- 清北学堂模拟赛d7t1 消失的数字
题目描述 现在,我的手上有 n 个数字,分别是 a1; a2; a3; :::; an.我现在需要删除其中的 k 个数字.当然我不希望随随便便删除,我希望删除 k个数字之后,剩下的 n - k 个数中 ...
- 清北学堂模拟赛d6t4 数组异或
分析:直接O(n^3)做是只有50分的,可以加一点小小的优化,就是c[k]可以从c[k-1]得到,但是还是只有60分,从宏观意义上是不能继续优化了.对于这类涉及到位运算的性质的题目,将每个数转化成二进 ...
随机推荐
- AD9850驱动程序--MSP430版本
前段时间忙着画板子搞运放搞滤波了,程序更新的少,发现MSP430不是太好用,尤其Timer,不过也与我使用内部晶振有关,产生正玄波之前用MSP430发出PWM,再进行滤波变为正弦波太麻烦了,这次改用D ...
- 使用display:flex;实现垂直水平居中
body,div{margin:0px;padding:0px;} .flex-container{display:flex;height:300px;background-color:#ddd;ju ...
- PCB SQL SERVER 正则应用实例
我们用过SQL SERVER的都知道,SQL SERVER它本身是不自带正则表达式的,因为没有,所以基本都没用过啊, 但我们在C#中对文本匹配用正则的方式处理非常好用,省得你写一堆代码实现匹配,多简洁 ...
- E20170926-mk
validation n. 确认; proposal n. 建议; 提议; 求婚; 〈美〉投标; teaser n. 戏弄者,喜欢戏弄别人的人; 棘手的问题; batch n. 一批; 一 ...
- POJ3070Fibonacci
矩阵乘法裸题 求快速幂 #include<iostream> #include<cstdio> #define ll long long #define Mod 10000 u ...
- xfs文件备份恢复篇一vm中linux新增磁盘
XFS提供了 xfsdump 和 xfsrestore 工具协助备份XFS文件系统中的数据.xfsdump 按inode顺序备份一个XFS文件系统.centos7选择xfs格式作为默认文件系统,而且不 ...
- BZOJ 2300凸包+离线
思路: 倒着加显然吧 动态维护这个凸包就好了 //By SiriusRen #include <bits/stdc++.h> using namespace std; ; int n,m ...
- C#模拟百度登录并到指定网站评论回帖(一)
核心信息: 请求网址: https://passport.baidu.com/v2/api/?login请求方法: POST状态码: HTTP/1.1 200 OK请求头 //用户代理 Use ...
- python 根据数组生成图片
array = np.asarray(allBigPng, dtype=np.uint8)image = Image.fromarray(array, 'RGBA') image.save(outpu ...
- JS——回调函数
1.回调函数作为参数的形式进行使用 2.回调函数一定程度上达到了解耦效果(模块化.功能化) <script> console.log(op(1, 2, add)); console.log ...