关于dp部分的思考

Posted 狼狼子浪的后院

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于dp部分的思考相关的知识,希望对你有一定的参考价值。

dp部分小结

背包

背包主要是模型的构建。

01背包

选与不选,且只能选一个。

for(int i=1;i<=n;i++)
    for(int j=mt;j>=w[i];j--)
        dp[j]=max(dp[j],dp[j-w[i]]+v[i]);

完全背包

选与不选,可任意选。

for(int i=1;i<=n;i++)
    for(int j=w[i];j<=mt;j++)
        dp[j]=max(dp[j],dp[j-w[i]]+v[i]);

多重背包

选与不选,有数目限制。

  • 考虑二进制拆分,讲一个大小为n的物品拆成O(logn)个物品

分组背包

选与不选,每组只能选一个

区间

枚举区间断点

\\( dp_i,j=max(dp_i,k+dp_k+1,j) \\)

\\( dp_i,j=max(dp_i,k-1+dp_k+1,j+c_k) \\)

枚举区间最后一个点

数位

比较套路,只要确定好状态和限制就好了

ll dfs(int pos,int num,int lim,int d)
	if(!pos)return num==d;
	if(~dp[pos][num][lim][d])return dp[pos][num][lim][d];
	int ma=lim?bit[pos]:1;
	ll res=0;
	for(int i=0;i<=ma;i++)
		res+=dfs(pos-1,num+(i==1),lim&&i==ma,d);
	
	return dp[pos][num][lim][d]=res;

状压

最好提前预处理合法状态

  • 枚举子集
for(int i=st;i;i=(i-1)&st)
  • 判断是否冲突
if((s1&s2)||(s1&(s2<<1))||((s1<<1)&s2))continue;

环形

树形

换根

以上是关于关于dp部分的思考的主要内容,如果未能解决你的问题,请参考以下文章

关于后台部分业务重构的思考及实践

dpluoguP4796 关于图 想不到是状压dp (┬_┬)

关于技术规划管理架构的思考

关于技术规划管理架构的思考

关于思考

关于JAVA核心技术(卷一)读后的思考(用户自定义类,静态域和静态方法的思考以及方法参数)