(ps:本集合为Star_F总结的dp进阶知识,持续更新~。 转载本文章需要联系我,否则视为侵权!!)

前置知识:线性dp,背包,树形dp,区间dp

内容预览:

  • 状压dp
  • 数位dp
  • dp优化(前缀和,单调队列,斜率优化)

1. 状压dp:

思路:如果题目中 \(n\) 的范围特别小(\(<=20\)) 大概率可以状压dp

状态:f[i][j]:考虑到前 \(i\) 个,且已考虑的集合为 \(j\) (j为二进制数,1表示考虑,0表示不考虑)

的集合

(辅助知识:位运算)

例题:

  • P1171 售货员的难题

    dp[i][j] 表示从起点到第j号点 且到达时状态恰好为i的最短路

    比较简单的状压dp,之间看代码吧:
点击查看代码
#include<bits/stdc++.h>
using namespace std;
int f[1<<20][20],w[20][20],n;
int main(){
cin>>n;
memset(f,0x3f,sizeof f);
f[1][0]=0;
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
cin>>w[i][j];
for(int i=1;i<(1<<n);i+=2) //枚举状态
for(int j=0;j<n;j++){ //枚举下一步到达的点
if(!((i >> j) & 1)) continue;
for(int k=0;k<n;k++){ 枚举中介点
if(j==k) continue;
if(!(i>>k &1)) continue;
f[i][j]=min(f[i][j],f[i^(1<<j)][k]+w[k][j]);
}
}
int minn=2e9;
for(int i=0;i<=n-1;++i) minn=min(minn,f[(1<<n)-1][i]+w[i][0]);
cout<<minn<<endl;
return 0;
}
  • P1896 [SCOI2005] 互不侵犯

    思路:f[i][j][s]就表示在只考虑前i行时,在前i行(包括第i行)有且仅有s个国王,且第i行国王的情况是编号为j的状态时情况的总数。而k就代表第i-1行的国王情况的状态编号。
点击查看代码
	#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;
int sit[2000],gs[2000];
int cnt=0;
int n,yong;
long long f[10][2000][100]={0};
void dfs(int he,int sum,int node)//预处理出每一个状态
{
if(node>=n)//如果已经处理完毕(注意是大于等于)
{
sit[++cnt]=he;
gs[cnt]=sum;
return;//新建一个状态
}
dfs(he,sum,node+1);//不用第node个
dfs(he+(1<<node),sum+1,node+2);//用第node个,此时node要加2,及跳过下一个格子
}
int main()
{
scanf("%d%d",&n,&yong);
dfs(0,0,0);
for(int i=1;i<=cnt;i++)f[1][i][gs[i]]=1;//第一层的所有状态均是有1种情况的
for(int i=2;i<=n;i++)
for(int j=1;j<=cnt;j++)
for(int k=1;k<=cnt;k++)//枚举i、j、k
{
if(sit[j]&sit[k])continue;
if((sit[j]<<1)&sit[k])continue;
if(sit[j]&(sit[k]<<1))continue;//排除不合法国王情况
for(int s=yong;s>=gs[j];s--)f[i][j][s]+=f[i-1][k][s-gs[j]];//枚举s,计算f[i][j][s]
}
long long ans=0;
for(int i=1;i<=cnt;i++)ans+=f[n][i][yong];//统计最终答案,记得用long long
printf("%lld",ans);
return 0;
}

2. 数位dp:

以一个数的数位进行dp,一般为求一个区间满足某些条件的数

通常把区间改为\((1...r) - (1...l-1)\)

例题:

点击查看代码
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector> using namespace std; const int N = 11; int f[N][10]; void init()
{
for (int i = 0; i <= 9; i ++ ) f[1][i] = 1; for (int i = 2; i < N; i ++ )
for (int j = 0; j <= 9; j ++ )
for (int k = 0; k <= 9; k ++ )
if (abs(j - k) >= 2)
f[i][j] += f[i - 1][k];
} int dp(int n)
{
if (!n) return 0; vector<int> nums;
while (n) nums.push_back(n % 10), n /= 10; int res = 0;
int last = -2;
for (int i = nums.size() - 1; i >= 0; i -- )
{
int x = nums[i];
for (int j = i == nums.size() - 1; j < x; j ++ )
if (abs(j - last) >= 2)
res += f[i + 1][j]; if (abs(x - last) >= 2) last = x;
else break; if (!i) res ++ ;
} for (int i = 1; i < nums.size(); i ++ )
for (int j = 1; j <= 9; j ++ )
res += f[i][j]; return res;
} int main()
{
init(); int l, r;
cin >> l >> r;
cout << dp(r) - dp(l - 1) << endl; return 0;
}
  • CF628D

    递归做法,枚举到那一位,现在的属性,有没有什么限制
点击查看代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int mod = 1e9+7;
ll m,d,a[2005],len,f[2005][2005];
char l[2005],r[2005];
ll dfs(int u,int sum,int yaoqiu){
if(u>len) return sum==0?1:0;
if(!yaoqiu&&f[u][sum]!=-1) return f[u][sum];
ll tmp=0,maxx=yaoqiu==1?a[u]:9;
if(u%2==1){
for(int i=0;i<=maxx;i++)
if(i!=d) tmp=(tmp+dfs(u+1,(sum*10+i)%m,yaoqiu&&(i==maxx)))%mod;
}
else{
for(int i=0;i<=maxx;i++)
if(i==d) tmp=(tmp+dfs(u+1,(sum*10+i)%m,yaoqiu&&(i==maxx)))%mod;
}
if(!yaoqiu) f[u][sum]=tmp;
return tmp;
}
ll dp(char *s){
memset(f,-1,sizeof(f));
len=strlen(s+1);
for(int i=1;i<=strlen(s+1);i++) a[i]=s[i]-'0';
return dfs(1,0,1);
}
bool check(char *s){
len=strlen(s+1);
int x=0;
for(int i=1;i<=len;i++){
int y=s[i]-'0';
x=(x*10+y)%m;
if(i&1){
if(y==d)
return false;
}
else{
if(y!=d)
return false;
}
}
return !x;
}
int main(){
cin>>m>>d>>l+1>>r+1;
cout<<(dp(r)-dp(l)+check(l)+mod)%mod;
return 0;
}

3.dp优化:

DP进阶合集的更多相关文章

  1. Codeforces - tag::dp 大合集 [占坑 6 / inf]

    Gym - 100753J 某国家仅有金币和银币两种货币,起汇率为g,纪念品市场有n个商人和商品,商人结帐只用银币,并且把一堆银币装在袋子里,分为三种类型,分别按向下/向上/四舍五入取整(其中向上的优 ...

  2. DP小合集

    1.Uva1625颜色的长度 dp[i][j]表示前一个串选到第i个 后一个串选到第j个 的最小价值 记一下还有多少个没有结束即dp2 记一下每个数开始和结束的位置 #include<cstdi ...

  3. 【视频合集】极客时间 react实战进阶45讲 【更新中】

    https://up2.v.sharedaka.com/video/ochvq0AVfpa71A24bmugS5EewhFM1553702519936.mp4 01 React出现的历史背景及特性介绍 ...

  4. dp合集 广场铺砖问题&&硬木地板

    dp合集 广场铺砖问题&&硬木地板 很经典了吧... 前排:思想来自yali朱全民dalao的ppt百度文库免费下载 后排:STO朱全民OTZ 广场铺砖问题 有一个 W 行 H 列的广 ...

  5. 9.15 DP合集水表

    9.15 DP合集水表 显然难了一些啊. 凸多边形的三角剖分 瞄了一眼题解. 和蛤蛤的烦恼一样,裸的区间dp. 设f[i][j]表示i~j的点三角剖分最小代价. 显然\(f[i][i+1]=0,f[i ...

  6. 9.14 DP合集水表

    9.14 DP合集水表 关键子工程 在大型工程的施工前,我们把整个工程划分为若干个子工程,并把这些子工程编号为 1. 2. --. N:这样划分之后,子工程之间就会有一些依赖关系,即一些子工程必须在某 ...

  7. DP+贪心水题合集_C++

    本文含有原创题,涉及版权利益问题,严禁转载,违者追究法律责任 本次是最后一篇免费的考试题解,以后的考试题目以及题解将会以付费的方式阅读,题目质量可以拿本次作为参考 本来半个月前就已经搞得差不多了,然后 ...

  8. 掘金 Android 文章精选合集

    掘金 Android 文章精选合集 掘金官方 关注 2017.07.10 16:42* 字数 175276 阅读 50053评论 13喜欢 669 用两张图告诉你,为什么你的 App 会卡顿? - A ...

  9. Android 自定义View合集

    自定义控件学习 https://github.com/GcsSloop/AndroidNote/tree/master/CustomView 小良自定义控件合集 https://github.com/ ...

  10. [题解+总结]动态规划大合集II

    1.前言 大合集总共14道题,出自江哥之手(这就没什么好戏了),做得让人花枝乱颤.虽说大部分是NOIP难度,也有简单的几道题目,但是还是做的很辛苦,有几道题几乎没思路,下面一道道边看边分析一下. 2. ...

随机推荐

  1. ubuntu18.04最小化安装

    ubuntu 18.04虚拟机安装 镜像下载地址: https://releases.ubuntu.com/18.04/ubuntu-18.04.6-live-server-amd64.iso 创建虚 ...

  2. Swift 与 Objc Exception

    一.背景 Swift具备完善的Error handle机制,对于纯Swift下面的Error,在编码的时候能够正确处理. 在使用try? 处理抛出Error的方法的时候,会忽略Error,直接返回ni ...

  3. java.sql.SQLException: MONTH 报错解决方法

    idea控制台报错:java.sql.SQLException: MONTH Error attempting to get column 'xxx' from result set. Cause: ...

  4. idea 使用 mvn clean package 报错 Could not create local repository at

    使用 mac 版本的 idea 打包使用打包命令 mvn clean package 总是报错: [ERROR] Could not create local repository at /Repos ...

  5. OpenSearch 与 Elasticsearch:哪个开源搜索引擎适合您?

    当谈论到搜索引擎产品时,Elasticsearch 和 OpenSearch 是两个备受关注的选择.它们都以其出色的功能和灵活性而闻名,但在一些方面存在一些差异.在本文中,我们将从功能和延展性.工具与 ...

  6. MYSQL 连接数据库过程中发生错误,检查服务器是否正常连接字符串是否正确,错误信息:未将对象引用设置到对象的实例。

    一: 中文提示 : 连接数据库过程中发生错误,检查服务器是否正常连接字符串是否正确,错误信息:未将对象引用设置到对象的实例.DbType="MySql";ConfigId=&quo ...

  7. 20 套监控平台统一成 1 套 Flashcat,国泰君安监控选型提效之路

    author:宋庆羽-国泰君安期货 运维工作最重要的就是维护系统的稳定性,其中监控是保证系统稳定性很重要的一环.通过监控可以了解系统的运行状态,及时发现问题和系统隐患,有助于一线人员快速解决问题,提高 ...

  8. http与https详解

    1.http HTTP协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准.HTTP是一个基于TC ...

  9. Java中的Collection集合(单列集合)

    1.集合概述 集合:集合是java中提供的一种容器,可以用来存储多个数据. 集合与数组的区别: (1)数组的长度是固定的,集合的长度是可变的. (2)数组中存储的是同一类型的元素,可以存储基本数据类型 ...

  10. TiKV 源码分析之 PointGet

    作者:来自 vivo 互联网存储研发团队-Guo Xiang 本文介绍了TiDB中最基本的PointGet算子在存储层TiKV中的执行流程. 一.背景介绍 TiDB是一款具有HTAP能力(同时支持在线 ...