poj2436,poj3659,poj2430
这两题都体现了dp的核心:状态
dp做多就发现,状态一设计出来,后面的什么都迎刃而解了(当然需要优化的还要动动脑筋);
先说比较简单的;
poj2436 由题得知病毒种数<=15很小,于是我们就容易想到将病每个牛携带的病毒抽象成15位的二进制数
0表示这种病毒不存在,1表示病毒存在,于是设cowi携带的病毒转化为二进制数为a,cowj为b
则如果挤cowi和cowj,那么所含病毒数为a or b,由此dp就显然了;
- var dp:array[..,..] of longint; //表示所含病毒数为j的情况下最多可以挤多少只牛
- w,f:array[..] of longint;
- s,ans,x,i,j,n,m,k,t,y,k1,k2:longint;
- function prework(x:longint):longint; //预处理数字代表的病毒种类数目
- var t:longint;
- begin
- t:=;
- while x<> do
- begin
- t:=t+x mod ;
- x:=x div ;
- end;
- exit(t);
- end;
- begin
- readln(t,m,k);
- s:= shl m-;
- f[]:=;
- for i:= to s do
- begin
- f[i]:=prework(i);
- dp[,i]:=-;
- end;
- for i:= to t do
- begin
- read(x);
- if x>k then readln
- else begin
- n:=n+;
- w[n]:=;
- for j:= to x do //转化为二进制
- begin
- read(y);
- w[n]:=w[n]+ shl (y-);
- end;
- end;
- end;
- dp[,]:=;
- k1:=;
- k2:=;
- ans:=;
- for i:= to n do //dp
- begin
- k1:=k1 xor ; //滚动数组
- k2:=k2 xor ;
- dp[k2]:=dp[k1];
- for j:= to s do
- begin
- x:=j or w[i]; //位运算
- if (f[x]<=k) and (f[j]<=k) and (dp[k1,j]>=) then
- dp[k2,x]:=max(dp[k2,x],dp[k1,j]+);
- ans:=max(dp[k2,x],ans);
- end;
- end;
- writeln(ans);
- end.
poj2436
写的比较随意,有些地方还可以优化 O(n*2^m)是可以在1s出来的,实际813ms(悬)
poj3659是树的最小支配集
这题贪心也是正确方法,但这里我介绍的是treedp
对于当前节点i,容易想的两种状态f[i,1]表示在i节点建立发射塔(属于支配集)
所以它的孩子节点状态就随意了,每个子节点选个最小的状态就行了;
f[i,0]表示在i节点不建立发射塔,但i和其子树都被覆盖了
所以f[i,0]=signma(min(f[j,0],f[j,1]))-min(f[k,0]-f[k,1]); j表示i的所有孩子,而k表示其中有一个孩子一定要属于支配集
注意不要漏了一种情况:那就是i可以不被儿子覆盖而被它的父亲覆盖,并且它的子树都是全覆盖的
f[i,2]=signma(min(f[j,0],f[j,1]))
最后的ans=min(f[root,0],f[root,1]);
实现起来还是很容易的,dfs到叶子然后想上更新
值得注意的是,题目给出的相邻结点而非父子关系,所以用图的形式存然后以任意一点做treedp即可
poj2430是使用k个矩形覆盖所用奶牛的最小覆盖面积
同样要设计好状态
设f[i,j,k]表示到覆盖到第i只奶牛使用j个木板,k表示覆盖结尾的状态,显然有4种
1.上下都圈而且上下是属于同一次圈的
2.上下都圈而且上下是不属于同一次圈的,属于两次圈的
3.只圈上面的
4.只圈下面的
然后就轻松了
code:复杂度O(nk+nlog2n)
- const max=;
- var f:array[..,..,..] of longint;
- a,b:array[..] of longint;
- i,j,k1,k2,n,k,m,w,ans,t:longint;
- function findmin(t:longint):longint;
- var p,k:longint;
- begin
- p:=max;
- for k:= to do
- p:=min(p,f[k1,j-t,k]);
- exit(p);
- end;
- procedure sort(l,r: longint); //按列排序,上下都有牛时1在前2在后,这样处理dp的时候方便多
- var i,j,x,y: longint;
- begin
- i:=l;
- j:=r;
- x:=a[(l+r) div ];
- y:=b[(l+r) div ];
- repeat
- while (a[i]<x) or (a[i]=x) and (b[i]<y) do inc(i);
- while (x<a[j]) or (a[j]=x) and (b[j]>y) do dec(j);
- if not(i>j) then
- begin
- swap(a[i],a[j]);
- swap(b[i],b[j]);
- inc(i);
- j:=j-;
- end;
- until i>j;
- if l<j then sort(l,j);
- if i<r then sort(i,r);
- end;
- procedure doit1;
- begin
- f[k2,j,]:=min(f[k2,j,],f[k1,j,]+*(a[i]-a[i-]));
- f[k2,j,]:=min(findmin()+,f[k2,j,]);
- end;
- procedure doit2;
- var p:longint;
- begin
- f[k2,j,]:=min(f[k1,j,]+*(a[i]-a[i-]),f[k2,j,]);
- p:=min(min(f[k1,j-,],f[k1,j-,]),f[k1,j-,]);
- f[k2,j,]:=min(f[k2,j,],p+a[i]-a[i-]+);
- if j->= then
- f[k2,j,]:=min(f[k2,j,],findmin()+);
- end;
- procedure doit(x:longint);
- var p:longint;
- begin
- p:=min(f[k1,j,x],f[k1,j,]);
- f[k2,j,x]:=min(f[k2,j,x],p+a[i]-a[i-]);
- f[k2,j,x]:=min(f[k2,j,x],findmin()+);
- end;
- begin
- readln(n,k,m);
- for i:= to n do
- readln(b[i],a[i]);
- sort(,n);
- for i:= to k do //初始化
- for j:= to do
- begin
- f[,i,j]:=max;
- f[,i,j]:=max;
- end;
- i:=;
- f[,,]:=;
- if a[i]=a[i+] then
- begin
- i:=;
- f[,,]:=;
- end
- else begin
- i:=;
- if b[]= then f[,,]:=
- else f[,,]:=;
- end;
- k1:=;
- k2:=;
- while i<=n do
- begin
- k1:=k1 xor ; //滚动数组
- k2:=k2 xor ;
- if a[i]=a[i+] then w:= else w:=;
- for j:= to k do
- begin
- for t:= to do
- f[k2,j,t]:=max;
- doit1; //做4个状态,方程式自己动手比划一下就明白了
- doit2;
- if w= then
- begin
- if b[i]= then
- doit()
- else doit();
- end;
- end;
- i:=i+w;
- end;
- ans:=max;
- for i:= to do
- ans:=min(ans,f[k2,k,i]);
- writeln(ans);
- end.
上述三道题都是非常好的设计状态题,状态是用dp解决问题的关键
特别poj2430一设计出状态,dp立马迎刃而解
poj2436,poj3659,poj2430的更多相关文章
- 10.22~10.28一周经典题目整理(meeting,BZOJ4377,POJ3659)
meeting:给正n边形每个点染上黑色或者白色,问有多少个同色的等腰三角形. 以正五边形为例这里将最上面的点作为顶点,得到若干对相等的腰 ,注意到以最上面的点作为顶点的等腰三角形的个数,等于颜色相等 ...
- 逆天通用水印支持Winform,WPF,Web,WP,Win10。支持位置选择(9个位置 ==》[X])
常用技能:http://www.cnblogs.com/dunitian/p/4822808.html#skill 逆天博客:http://dnt.dkil.net 逆天通用水印扩展篇~新增剪贴板系列 ...
- MySQL主从环境下存储过程,函数,触发器,事件的复制情况
下面,主要是验证在MySQL主从复制环境下,存储过程,函数,触发器,事件的复制情况,这些确实会让人混淆. 首先,创建一张测试表 mysql),age int); Query OK, rows affe ...
- Oracle安装部署,版本升级,应用补丁快速参考
一.Oracle安装部署 1.1 单机环境 1.2 Oracle RAC环境 1.3 Oracle DataGuard环境 1.4 主机双机 1.5 客户端部署 二.Oracle版本升级 2.1 单机 ...
- Syscall,API,ABI
系统调用(Syscall):Linux2.6之前是使用int0x80(中断)来实现系统调用的,在2.6之后的内核是使用sysentry/sysexit(32位机器)指令来实现的系统调用,这两条指令是C ...
- 【夯实PHP基础】PHP数组,字符串,对象等基础面面观
本文地址 分享提纲 1.数组篇 2.字符创篇 3.函数篇 4.面向对象篇 5.其他篇 /*************************** 一.数组篇 Begin***************** ...
- MSSQL 事务,视图,索引,存储过程,触发器
事务 事务是一种机制.是一种操作序列,它包含了一组数据库操作命令,这组命令要么全部执行,要么全部不执行. 在数据库系统上执行并发操作时事务是作为最小的控制单元来使用的.这特别适用于多用户同时操作的数据 ...
- 谁偷了我的热更新?Mono,JIT,iOS
前言 由于匹夫本人是做游戏开发工作的,所以平时也会加一些玩家的群.而一些困扰玩家的问题,同样也困扰着我们这些手机游戏开发者.这不最近匹夫看自己加的一些群,常常会有人问为啥这个游戏一更新就要重新下载,而 ...
- Atitit 知识管理的重要方法 数据来源,聚合,分类,备份,发布 搜索
Atitit 知识管理的重要方法 数据来源,聚合,分类,备份,发布 搜索 1.1. Rss 简易信息聚合(也叫聚合内容 Really Simple Syndication1 1.1. Rss 简易信息 ...
随机推荐
- php function 定义时函数名前加&符号的意义
看了很多帖子,但是都不能理解,又去看了很多资料,终于名白了.记下备忘. 问题:php在声明函数时,函数名前面的&符号有什么用? 一直想不通.很多帖子说类似于变量的$a=&$b,但是$b ...
- Spark小课堂Week4 从控制台看Spark逻辑结构
Spark小课堂Week4 从控制台看Spark逻辑结构 层级关系: 从监控控制台,我们可以看到如下关系: 一个 Job 包含 n Stage 一个 Stage 包含 n Task Job0解决什么问 ...
- Beaglebone Back学习四(GPIO实验)
GPIO Beaglebone Back开发板引出了92个引脚,其中只有65个GPIO口可通过配置使用,由于引脚具有“复用”的特性,大约每个引脚有8种工作模式(Beagle System Refere ...
- excle,aspose.cells 公式字段值取不到 xmls转xml
问题: 一,单元格如果是公式的,读出值为0 aspose.cells 4.4.0.5版本 由于太低,读xmls后缀的excel文件时,发现如果此列是公式算出来的,值是获取不到的.获取到的值一直是0 二 ...
- 1074: [SCOI2007]折纸origami - BZOJ
Description 桌上有一张边界平行于坐标轴的正方形纸片,左下角的坐标为(0,0),右上角的坐标为(100,100).接下来执行n条折纸命令.每条命令用两个不同点P1(x1,y1)和P2(x2, ...
- ExtJS4.2学习(八)表格限制输入数据的类型(转)
鸣谢:http://www.shuyangyang.com.cn/jishuliangongfang/qianduanjishu/2013-11-14/177.html --------------- ...
- pl/sql developer连接远程数据库
本地不安装oracle client程序,直接使用pl/sql developer连接远程数据库 考虑到机子本身资源有限,一个client会占用很多资源,尝试使用不安装客户端的方式进行远程连接. 需要 ...
- What are the advantages of logistic regression over decision trees?FAQ
What are the advantages of logistic regression over decision trees?FAQ The answer to "Should I ...
- netstat命令查看服务器运行情况
netstat -n|grep 80出现大量time_wait 在运行netstat -n|grep 80 | awk '/^tcp/ {++S[$NF]} END {for(a in S) prin ...
- python-append()方法
append() 方法向列表的尾部添加一个新的元素.只接受一个参数. >>> mylist = [1,2,3,4] >>> mylist [1, 2, 3, 4] ...