[DP之计数DP]

其实说实在 我在写这篇博客的时候 才刚刚草了一道这样类型的题 之前几乎没有接触过 接触过也是平时比赛的 没有系统的做过 可以说0基础

我所理解的计数dp就是想办法去达到它要的目的 而且一定要非常劲非常快 都是一个很小的数然后有很多种接下来的方案使得这个数一下子变很大

 

计数DP常用的有:组合和排列 然后要抽象的想 还有容斥定理(这的话经常考而且很难几乎不会做) 还有用前缀之类的进行优化转移 找到规律就可以搞了

慢慢给出例题慢慢说慢慢学 因为这个要不全AC要不全WA

 

[JLOI2013]地形生成

计数dp的第一题 看了题意一下子懵比 感受到了计数dp的厉害性 表示连暴力都不会打

然后看题解 自己推了做了死吭了一天 (妈的旁边合唱室的脑瓜有病啊我去 叫了一整天还不给我唱征服..)

 

首先我们发现 如果小的插在大的前面是完全没有影响的 所以我们按两个关键字从大到小排 这样的话以后插入都没有影响

看上去好像第一问简单一点 就是求合法的标号序列 也就是合法的序列有多少个 那么想一想嘛 对于同一个高度的 你找到前面的你能插到哪里 再加上高度相同的而且在前面的

为什么要加上前面的呢 你想想 前面是不是也是找前面的 那么他们找了的话其实我当前的可以把这个位置忽略掉 并且前面的还会把它找的前面给挤出去 然后还多了个位置

比如说 x y 都在我承受的范围内 就有三个可以放的地方但是加上了前面高度相同的还有一个p 也就是变成了 x p y 那么是不是多了个位置啊 就有四个地方可以插入了

 

然后就是高度序列的问题 高度序列其实想一想就是同一个高度的 然后两两的位置不能变 这也和我们两个关键字排序有关 小的在前大的在后 这样的话保证高度相同时后面的可以放在前面去

不能交换的话 那么怎么做呢 其实也很简单 想想就好

设F[i][j]表示现在是第i座山放在第j个位置上 占时对于这个高度有多少种方法

那么这个高度第一座山所有这座山能放位置的F[i][j]=1

考虑下一座山 不能放在上一座山的前面 不然就相当于这一座山是第一座 上一座是第二座 就交换了

所以的话F[i+1][j]=sigma(F[i][1..j-1]) 就是上一座山放在我前面的都可以继承下来 然后的话搞一个前缀和优化一下

F[i+1][j]=F[i+1][j-1]+F[i][j-1] 也就是说前面能选的我也可以选 前面不可以选的我可以选就是前面那座山在前面的位置

然后每个最后的山的状态的和加起来就好了 这就代表了这个高度的山一起放的方案数 然后乘一下就好

代码贼短不用怕

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#define Maxn 1010
using namespace std;
const int Mod=2011;
pair<int,int>pr[Maxn];
bool Cmp(const pair<int,int> &x,const pair<int,int> &y){if(x.first!=y.first) return x.first>y.first; else return x.second<y.second;}
int F[Maxn][Maxn];
int main()
{int N; scanf("%d",&N);for(int i=1;i<=N;i++) scanf("%d%d",&pr[i].first,&pr[i].second);sort(pr+1,pr+N+1,Cmp); int ans1=1,ans2=1; memset(F,0,sizeof(F));for(int i=1;i<=N;){int now=i; while(now<N&&pr[now].first==pr[now+1].first) now++;for(int j=i;j<=now;j++){ans1=(ans1*(min(pr[j].second,i)+j-i))%Mod;if(j==i){F[j][0]=1; for(int k=1;k<min(pr[j].second,i)+j-i;k++) F[j][k]=(F[j][k-1]+F[j][k])%Mod;}else for(int k=0;k<min(pr[j].second,i)+j-i;k++) F[j][k]=(F[j][k-1]+F[j-1][k-1])%Mod;}int sum=0; for(int j=0;j<min(pr[now].second,i)+now-i;j++) sum+=F[now][j];ans2=(ans2*sum)%Mod; i=now+1;}return printf("%d %d",ans1,ans2),0;
}
/*
2
1 2
2 2
*/
View Code

 

Codeforce 382.E Ksenia and Combinatorics

好难啊啊啊 好想死啊 做了我一天半

题目有一个最大匹配数 有一个不同子树形态 数学老师其实教过我们做题要有化归思想

单单求子树形态我们可以有两种方法:

1.强制左树小于右树且左树和右树相同时 最小的数在左树

2.强制左树小于右树且相同时 /2

单单求最大匹配数我们可以有  F[i][0/1]表示与不与根匹配 转移显然

然后要合起来 怎么办呢 定义F[N][K][0/1]表示N个点最大匹配数为k然后最上面的点选不选

然后我们固定一个根

复制一下别人的图 其实C(k,i-1)就是选一边的 根节点固定不能变 然后因为上一个状态继承下一个状态的时候 下一个状态的根节点是可以变得 所以要两边分别乘k和(i-k-1)

然后没了 好多细节有点难打 注意相同节点个数的时候要除2(画图大概意会了一下想了好久不会证,大概是所有形态只是选的方式不同 形态是一样的) k=0是要*1 

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
using namespace std;
typedef long long LL;
const LL Mod=1e9+7;
LL N,K; LL C[60][60]; LL F[60][60][2];
void Pre()
{C[1][1]=1; for(LL i=1;i<=N;i++) C[i][0]=1;for(LL i=2;i<=N;i++) for(LL j=1;j<=i;j++) C[i][j]=(C[i-1][j-1]+C[i-1][j]);
}
int main()
{scanf("%I64d%I64d",&N,&K); Pre();F[0][0][1]=1; F[1][0][0]=1;for(LL p=2;p<=N;p++){for(LL q=0;q<=p/2;q++){for(LL i=0;i<=(p-1)/2;i++){for(LL j=0;j<=i/2;j++){LL k0=1,k1=1; if(i==p-i-1) k0++; if(i==p-i-1) k1++;LL A=i; LL B=p-i-1; if(A==0) A++;LL cz=((C[p-1][i]/k0)*A*B)%Mod;cz=(cz*F[i][j][1])%Mod; cz=(cz*F[p-i-1][q-j][1])%Mod;F[p][q][0]=(F[p][q][0]+cz)%Mod;cz=((C[p-1][i]/k1)*A*B)%Mod;cz=(cz*((F[i][j][1]*F[p-i-1][q-j-1][0])%Mod+(F[i][j][0]*F[p-i-1][q-j-1][1])%Mod+(F[i][j][0]*F[p-i-1][q-j-1][0])%Mod))%Mod;F[p][q][1]=(F[p][q][1]+cz)%Mod;}}}}printf("%I64d\n",(F[N][K][0]+F[N][K][1])%Mod);return 0;
}
View Code

 

 hdu5713 K个联通块

绝世好题啊(不是bzoj4300..)

首先N这么小 就应该想到什么组合容斥状压 然后又有一个K 很明显这是要转移的

F[sta][K]表示点的状态为sta 分成K份的方案数 那么我们考虑转移 先在状态中抽出一个点 然后和其余的点互相成为联通块

比如说这个状态有4个点 1 2 3 4 我把1抽出来 使得1 12 13 14 123 124 134成为联通块设为上一个状态s1 然后求解 F[sta][K]=Sigma(F[s1][1],F[sta^s1][k-1])

这样就没有遗漏的 这是liao教我的 因为这样保证了你1这个联通块是不同的 然后其他的块随便取 这样就保证结果都是不同的 而且1是一定要取得,全部都会取完

也就是1总得要属于一个联通块 然后你把联通块枚举出来 其它一定不同 而且一定要算了

但是我们需要做的是F[sta][1] 其实的话这个状态就可以转换成G[sta]-H[sta] G是这个状态所有的边的方案数 通过2^(边数)可以求出 然后H就是这个状态不联通的个数

H的求法类似于F H[sta]=H[s1]*G[sta^s1] 就是随便抽一个点出来 然后其它怎么连都不关我事 这样就每个和这个点的联通块都过了一变 保证不重复

求子集有点妙 自己看看代码意会

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#define Maxn 15
using namespace std;
typedef long long LL;
const int Mod=1e9+9;
struct node{int x,y,next;}edge[Maxn*Maxn*2]; int len,first[Maxn];
void ins(int x,int y){len++; edge[len].x=x; edge[len].y=y; edge[len].next=first[x]; first[x]=len;}
int T,K,N,M; inline int low_bit(int x){return x&(-x);}LL G[1<<Maxn]; LL F[Maxn][1<<Maxn]; LL H[1<<Maxn];
LL bit[Maxn*Maxn];
int main()
{scanf("%d",&T);for(int Tcase=1;Tcase<=T;Tcase++){scanf("%d%d%d",&N,&M,&K); len=0; memset(first,-1,sizeof(first));for(int i=1;i<=M;i++){int a,b; scanf("%d%d",&a,&b); if(a>=b) ins(a,b); else ins(b,a);}bit[0]=1; for(int i=1;i<=M;i++) bit[i]=(bit[i-1]<<1)%Mod;memset(F,0,sizeof(F)); memset(G,0,sizeof(G)); memset(H,0,sizeof(H));for(int i=0;i<(1<<N);i++){int sum=0;for(int x=1;x<=N;x++)for(int k=first[x];k!=-1;k=edge[k].next){int y=edge[k].y;if((i&(1<<(x-1)))&&(i&(1<<(y-1))))sum++;}G[i]=bit[sum];}for(int i=0;i<(1<<N);i++){int last=i-low_bit(i);for(int j=last;j;j=(j-1)&last)H[i]=(H[i]+(F[1][i-j]*G[j]))%Mod;F[1][i]=(G[i]-H[i]+Mod)%Mod;}for(int k=2;k<=K;k++)for(int i=0;i<(1<<N);i++){int last=i-low_bit(i);for(int j=last;j;j=(j-1)&last)F[k][i]=(F[k][i]+(F[1][i-j]*F[k-1][j]))%Mod;}printf("Case #%d:\n",Tcase);int ans=0; printf("%lld\n",F[K][(1<<N)-1]);}return 0;
}
View Code

 

转载于:https://www.cnblogs.com/wohenshuai/p/5901620.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/402921.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++程序设计(第2版)课后习题答案--第11章

11.9 定义分数类Rational...... View Code 1 #include<iostream.h>2 #include<stdlib.h>3 class Rational{4 private:5 int fm,fz;6 int getZdgys(int a,int b);7 public:8 Rational(){9 fm1;fz0; 10 } 11 Rational(int a,int b); 1…

el-table设置动态高度:height;el-table设置最大高度max-heigh

<template><div><!-- 表格 height绑定tHeight--><el-tableref"singleTable":data"tableData":height"tHeight":max-height"maxHeight"><el-table-columnprop"date"label"日期"width&q…

C#控制台程序中处理2个关闭事件的代码实例

From: http://www.cnblogs.com/lvxiangjack/p/5363627.html 我们开发的控制台应用&#xff0c;在运行阶段很有可能被用户CtrlC终止或是被用户直接关闭。如果我们不希望用户通过CtrlC终止我们的程序&#xff0c;就需要对CtrlC或关闭事件作处理。 处理方法 在.net平台下Console类…

字典表左右选择

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns"http://www.w3.org/1999/xhtml"><head><title>管理中心 - 添加新配送点 &l…

Oracle内部错误:ORA-07445[kcflfi()+466] [INT_DIVIDE_BY_ZERO]一例

一套Windows上的11.2.0.1单实例数据库在database open阶段出现了ORA-07445:core dump [kcflfi()466] [INT_DIVIDE_BY_ZERO] [] [PC:0x500282E] [] []内部错误&#xff0c;具体的出错日志如下: LOG CONTENTALERT.LOGStarting ORACLE instance (normal) LICENSE_MAX_SESSION 0 L…

提交本地项目到github

要托管到github&#xff0c;那你就应该要有一个属于你自己的github帐号&#xff0c;所以你应该先到github.com注册 打开浏览器 在地址栏输入地址&#xff1a;github.com 填写用户名、邮箱、密码 点击Sign up即可简单地注册 2完成注册&#xff0c;进入github平台&#xff0c; 点…

一个能自动搜索源文件并自动推导的Makefile

From: http://blog.csdn.net/yuliying/article/details/49635485 这份makefile可以将当前makefile所在文件夹以及所有子文件夹中的cpp文件打包成静态库和动态库. 稍作修改目标也可以用来编译为可执行文件。 自动生成所有依赖关系&#xff0c;修改任何文件都可以触发重新编译相应…

(转)android WebView loadData不能解析(找不到网页)

public void loadData (String data, String mimeType, String encoding) loadData() 中的html data中不能包含#, %, \, ?四中特殊字符&#xff0c;出现这种字符就会出现解析错误&#xff0c;显示找不到网页还有部分html代码。因为css中经常用#, %等字符&#xff0c;所以大部…

C++11 std::bind std::function 高级用法

From: http://blog.csdn.net/eclipser1987/article/details/24406203 从最基础的了解&#xff0c;std::bind和std::function [cpp] view plaincopy/* * File: main.cpp * Author: Vicky.H * Email: eclipser163.com */ #include <iostream> #include <fun…

fragment+viewpager+tablayou实现滑动切换页面

本文目标&#xff1a;实现滑动切换页面 首先&#xff0c;Tablayout控件就需要添加design library&#xff0c;在android studio中添加依赖 compile ‘com.android.support:design:23.2.1’ 或者直接&#xff1a;File-->Project structure-->app-->Dependencies中单击加…

php 的命名空间 看鸟哥后的随笔

我以前貌似真心没有想过php的命名空间&#xff0c;我每次写文件都会记得不让类名相重&#xff0c; 看完命名空间了这个&#xff0c;我发现可以解决我的一部分问题 1 MyLove.php2 namespace Zj;3 class Application{4 public function toMyLove(){5 echo Marx is…

vue页面截图;H5页面截图;vue项目中将特定网页内容生成图片(截图);html2canvas截图

功能&#xff1a; 1.兼容 PC 和 Mobile&#xff1b; 2.对指定的区域进行截取&#xff1b; 3.可以控制截图大小&#xff1b; 4.截图生成base64图片地址 一、安装插件 npm install html2canvas --save 或 yarn add html2canvas二、在.vue页面引入使用 import html2canvas fro…

CentOS6.8升级gcc到4.8.5总结

From&#xff1a; http://www.cjjjs.com/paper/czxt/2017222114137150.aspx [摘要] 操作系统是CentOS6.8的32位版本&#xff0c;yum自带的gcc版本为4.4.7&#xff0c;不支持C11特性。所以需要升级到4.8.5&#xff0c;至少要升级到4.8.1才完全支持C11。本文提供了自动安装脚本和…

JAVA设计模式之【单例模式】

任务管理器案例 1.单例类 package Singleton;/*** Created by Jim on 2016/9/28.*/ public class TaskManager {private static TaskManager tm null;private TaskManager() {System.out.println("创建任务管理器");}public void displayProcesses() {System.out.pr…

myeclipse快捷键

Ctrl1 快速修复CtrlD: 删除当前行 CtrlQ 定位到最后编辑的地方 CtrlL 定位在某行 CtrlO 快速显示 OutLine CtrlT 快速显示当前类的继承结构 CtrlW 关闭当前Editer CtrlK 快速定位到下一个 CtrlE 快速显示当前Editer的下拉列表CtrlJ 正向增量查找(按下CtrlJ后,你所输入的…

vue下载static文件

将文件放在static静态文件夹下即可&#xff0c;如果放在src统计的static不行&#xff0c;那就放在src下级的static里 downLoadFile () {var elemIF document.createElement("iframe")// elemIF.src ../../static/政策精选模板.xlsx 这样写路径不行elemIF.src sta…

centos7.2 安装poco

下载地址: https://pocoproject.org/releases/poco-1.7.8/poco-1.7.8p3-all.tar.gz 安装&#xff1a; #!/bin/sh# 安装依赖库 # yum install openssl-devel mysql-devel# 默认方式不支持mysql #./configure --everything --omitData/ODBC,Data/SQLitemake -s#make -s install具…

ASP 错误处理

<% Option Explicit------------- 错误处理&#xff1a; ------------- 1.需在每一行可能发生错误的代码上使用"On Error" 和 "If Err.Number <> 0 Then ..." 结构。 注意作用域&#xff01; 2.On Error语句: 启用或禁用错误处理程序* On Error G…

【云计算】K8S DaemonSet 每个node上都运行一个pod

Kubernetes容器集群中的日志系统集成实践 Kubernetes是原生的容器编排管理系统&#xff0c;对于负载均衡、服务发现、高可用、滚动升级、自动伸缩等容器云平台的功能要求有原生支持。今天我分享一下我们在Kubernetes集群中日志管理的实践方案。在这个方案中&#xff0c;除了Doc…

struct结构体初始化3种方法

From: http://blog.csdn.net/thdxs/article/details/8204118 struct是C中重要的ADT。但是在一般讲C的书中&#xff0c;往往只介绍了struct的定义、顺序初始化及位域。      为了方便后面的介绍&#xff0c;先定义一个struct类型&#xff1a;    struct User    {    …