今天刷的数位dp 第一题看了题解以后知道了数位dp的基本板子,写数位dp的方式(运用记忆化递归的方法)已经基本固定。

那么接下来的难点主要还是对于题目描述的问题,如何抽象成dp中的状态。就今天刷的题来看,dp数组第一维一般为第i位数,这是数位dp的一般表示数的方式。而数组究竟还要加几维就要看题目要求的东西。

如下题:

http://acm.hdu.edu.cn/showproblem.php?pid=3709

题意即求:

对于某个 number,你可以 fix a pivot 在某位,然后如果分成的左右两部分的 sigma(d[i] * | i - fixloc |)相等,则它是 Balanced Number。

统计区间 [a,b] 中Balance Number 的个数。(引用https://blog.csdn.net/dgq8211/article/details/9302069)

这个题目问的是满足条件的最大总数。故dp数组(不管几维)=当前状态的最大总数。

那么问题用数位dp 关注数字本身属性的思想,可以抽象出一个状态即支点的位置[x]。

//除此,与问题结果直接相关的即支点两端的力矩差[sum]。

因为数位dp是(貌似dp都是)枚举所有情况再找到最优解的,所以一定会有一个状态为问题所要求满足的东西。以该题看,条件要求满足的就是支点两边的力矩差=0,那么力矩差就一定是dp数组里的一维了。

综上两个状态发现最大总数就是各个点为支点所有满足力矩差为0的情况的总和sum。

可以将所有的情况列出。此时思考dp数组结束,即dp[pos][x][sum]。

找到正确的dp数组后就可以开心的套板子再调整细节等AC了~~~

(这题AC代码可以从上面的链接看,我偷懒不发了)

其实如果能将问题抽象为数学函数那么能更加直观的发现状态,如题目要求找到(0,n)上所有能被13整除的数的总数那满足要求的x=cigma(n%13==0) dp数组即cigma(),状态就是数n和n%13,(也就是自变量和与自变量相关的运算)。

可得dp[pos][13]。

#include<cstdio>
#include<cstring>
int dp[][];
int digit[];
int n;
int dfs(int pos,int mod ,int limit)
{
if(pos==-)return mod==;
if(!limit&&dp[pos][mod]!=-)return dp[pos][mod];
int tmp=,mm,;
int up=limit?digit[pos]:;
for(int i=;i<=up;i++)
{
mm=(mod*+i)%;
tmp+=dfs(pos-,mm,limit&&i==digit[pos]);
}
if(!limit)dp[pos][mod]=tmp;
return tmp;
}
int solve(int x)
{
int k = x;
int pos = ;
while(k)
{
digit[pos++]=k%;
k/=;
}
return dfs(pos-,,);
}
int main()
{
memset(dp,-,sizeof(dp));
while(~scanf("%d",&n))
{
printf("%d\n",solve(n));
}
return ;
}

数位dp对于状态描述与发现的一些感悟的更多相关文章

  1. Codeforces Round #235 (Div. 2) D. Roman and Numbers (数位dp、状态压缩)

    D. Roman and Numbers time limit per test 4 seconds memory limit per test 512 megabytes input standar ...

  2. HDU 4352 XHXJ's LIS (数位DP+LIS+状态压缩)

    题意:给定一个区间,让你求在这个区间里的满足LIS为 k 的数的数量. 析:数位DP,dp[i][j][k] 由于 k 最多是10,所以考虑是用状态压缩,表示 前 i 位,长度为 j,状态为 k的数量 ...

  3. hdu4352 XHXJ's LIS(数位DP + LIS + 状态压缩)

    #define xhxj (Xin Hang senior sister(学姐)) If you do not know xhxj, then carefully reading the entire ...

  4. HDU 4352 XHXJ&#39;s LIS(数位dp&amp;状态压缩)

    题目链接:[kuangbin带你飞]专题十五 数位DP B - XHXJ's LIS 题意 给定区间.求出有多少个数满足最长上升子序列(将数看作字符串)的长度为k. 思路 一个数的上升子序列最大长度为 ...

  5. 咕咕(数位dp+AC自动机)

    咕咕(数位dp+AC自动机) 若一个字符串的字符集合是0~m-1,那么称它为m进制字符串.给出n个m进制字符串\(s_i\),每个字符串的权值为\(v_i\).对于另一个m进制字符串\(S\),设\( ...

  6. Balanced Number HDU - 3709 数位dp

    题意: 给出范围 算出 满足  选取一个数中任一一个 树作为支点  两边的数分别乘以到中心的距离和 左和等于右和   的数有多少个 数位DP题 状态转移方程为dp[pos][x][state]=dp[ ...

  7. BZOJ 4521 CQOI 2016 手机号码 数位DP

    4521: [Cqoi2016]手机号码 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 539  Solved: 325[Submit][Status ...

  8. 牛客多校第七场H Pair 数位dp理解

    Pair 题意 给出A B C,问x取值[1,A]和y取值[1,B]存在多少组pair<x,y>满足以下最小一种条件,\(x \& y >c\),\(x\) xor \(y& ...

  9. 【HDU 4352】 XHXJ's LIS (数位DP+状态压缩+LIS)

    XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

随机推荐

  1. 添加并启动MySQL服务

    1. 右键开始菜单,选择 2. 进入到MySQL安装目录下的bin目录,输入命令: mysqld.exe -install 3.启动mysql服务,输入命令: net start mysql

  2. dubbo配置文件加载顺序

    JVM 启动 -D 参数优先,这样可以使用户在部署和启动时进行参数重写,比如在启动时需改变协议的端口. XML 次之,如果在 XML 中有配置,则 dubbo.properties 中的相应配置项无效 ...

  3. shell的集合运算

    用cat,sort,uniq命令实现文件行的交集 .并集.补集 交集 $F_1 \cap F_2 $ cat f1 f2 | sort | uniq -d 并集 $F_1 \cup F_2 $ cat ...

  4. mysql 几个坑

    浮点转int类型 更新合并换成插入 不要频繁更新超过20个字节的字段 程序逻辑得到数据处理后才还回连接

  5. dsp

  6. ios键盘退出

    点击空白处退出键盘 -(void)touchesBegan:(nonnull NSSet<UITouch *> *)touches withEvent:(nullable UIEvent ...

  7. vs strcore.cpp(156) 内存泄漏

    在一个静态函数的线程回调中,一个cstring的对象没释放. 遇到这种问题: 1.查看所有的指针对象,有没有合适的回收 2.查看代码的malloc,看看有没有free 3.一点一点注释代码,定位位置

  8. Tokyocabinet/Tokyotyrant文档大合集

    1. 前言 这里不是我个人原创,是我对网络上整理到的资料的再加工,以更成体系,更方便研究阅读.主要是对其中跟主题无关的文字删除,部分人称稍做修改;本人无版权,您可以将本页面视为对参考页面的镜像.第二部 ...

  9. [SDOI2019]移动金币(博弈论+阶梯Nim+按位DP)

    首先可以把问题转化一下:m堆石子,一共石子数不超过(n-m)颗,每次可以将一堆中一些石子推向前一堆,无法操作则失败,问有多少种方法使得先手必胜? 然后这个显然是个阶梯Nim,然后有这样的结论:奇数层异 ...

  10. [LC] 322. Coin Change

    You are given coins of different denominations and a total amount of money amount. Write a function ...