DP
哈希表扁豆
此人不懒,但什么都没写
展开
-
P4767 [IOI2000]邮局(四边形不等式)
Problem高速公路旁边有一些村庄。高速公路表示为整数轴,每个村庄的位置用单个整数坐标标识。没有两个在同样地方的村庄。两个位置之间的距离是其整数坐标差的绝对值。邮局将建在一些,但不一定是所有的村庄中。为了建立邮局,应选择他们建造的位置,使每个村庄与其最近的邮局之间的距离总和最小。你要编写一个程序,已知村庄的位置和邮局的数量,计算每个村庄和最近的邮局之间所有距离的最小可能的总和。村庄总数<=3000,邮局总数<=300。Solution预处理出w(i,j)表示i~j个村庄放一个邮局的最原创 2022-04-06 15:45:23 · 827 阅读 · 0 评论 -
跳舞机(Tango Tango Insurrection, UVa 10618)
Problem题意如紫书,关于cost的计算感觉有些紫书上给的翻译不太好理解:本次无动作cost为0,本次动作和上次动作不一条腿cost为1,本次和上次动作同一条腿,没有涉及移动(只是踩了一下)cost为3,本次和上次动作同一条腿,本次为相邻移动和相对移动时cost分别为5和7。Solution条件较多,d(i,a,b,s)表示踩了前i个,当前左右脚在a,b,上次的移动状态为s时以后还会产生的最小代价。倒推,最终答案为d(0,1,2,0)。代码借鉴了网上高质量的代码,详见注释。Code#in原创 2022-03-28 00:09:02 · 438 阅读 · 0 评论 -
CF254E Dormitory
Problem每天有一定量的食物,食物的保质期都是两天即今天和明天,每天有一些朋友,可以用食物投喂他们,求n天最多投喂多少次朋友。Solution如果食物的保质期一天可以用贪心解决,食物的保质期是两天就要想办法将每一天当天新获得的食物的剩余体现在状态上(这样才能合法地转移)。a(i)为第i天所得食物,dp(i,j)表示前i天给i+1天剩了j食物所能投喂的最大次数,dp(i,j)=max(dp(i-1,k)+用a(i)-j+k最多能投喂的数量),注意对于每个i,j的范围是[0,a(i)]而非[0,a原创 2021-10-29 12:19:22 · 103 阅读 · 0 评论 -
【模板】最小斯坦纳树
ProblemSolution状压dp,dp(i,s)表示i为根包含点集s的最小权值和。用floyd预处理出两点间的最短路,dijkstra或spfa也可。分两种情况转移:i度数为1和i度数不为1。i度数为1:枚举相邻点j,dp(i,s)=min(dp(i,s),dp(j,s)+dis(i,j))。i度数不为1:枚举子集,dp(i,s)=min(dp(i,sub)+dp(i,s^sub))。注意转移状态的次序,从状压dp的角度考虑也有别的转移方法,不过这种最右,时间复杂度n2 * 2k+n原创 2021-08-30 17:39:29 · 161 阅读 · 0 评论 -
J - Joining Capitals(最小斯坦纳树变形)
Problem给定平面n个点的坐标,其中前k个为选中的点,求包含这k个点的最小代价且这k个点必须作为树上的叶子结点。一开始想乱暴,查了查是个斯坦纳树,之前听都没听说过。斯坦纳树斯坦纳树问题是组合优化问题,最小斯坦纳树允许在给定点外增加额外的点,使生成的最短网络开销最小。Pollak-Gilbert猜想:平面上任意n点集,斯坦纳最小树长与最小生成树之长的比值的最小值是sqrt(3)/2。Solution通过状压DP解决最小斯坦纳树问题,dp[i][S]表示已i为根包含集合S中所有点的最原创 2021-08-25 20:26:00 · 194 阅读 · 0 评论 -
HDU - 5009 Paint Pearls(链表优化DP)
Problem给一段染色的代价是这一段不同颜色数的平方,求染完序列的最小代价。Solution动态转移方程显而易见,但是裸的DP会T。通过观察可以发现,当前枚举的断点如果可能成为答案断点的左边一定是右边这一区间没出现过的数。因此我们可以用链表维护,用每个数最新出现的位置更新链表,同时最终答案一点小于等于n,每次枚举只需枚举sqrt(i)次即可。场上想不出优化时可以直接打一下转移的表观察看看。Code#include <iostream>#include <map>#i原创 2021-08-12 17:06:10 · 129 阅读 · 0 评论 -
Tunnels(状压DP模板题)
Problem求走过所有隧道所需的最小时间。Solution隧道总数很小,直接状态压缩。dp(i,j)表示已经走完的状态为i,当前在j所需要的最小时间。首先bfs预处理出不同隧道间的距离,将当前已经走过的隧道压缩成二进制数从小到大枚举状态,枚举每个状态的当前所在隧道,枚举当前隧道所能到达的隧道。Code#include <iostream>#include <map>#include <cmath>#include <cstdio>#incl原创 2021-08-11 20:11:27 · 154 阅读 · 0 评论 -
Contest Setting
题意有n个题目,每个题目都有一个难度,从里面选出k个难度不同的题目。赛时思路dp[i][j]表示选出的最后一个题的题目难度为i,已选出题数为j时的方案数,num[i]表示难度为i的题目个数,dp(i+1,j)=(∑k=j−1idp(k,j−1))∗num(i)dp(i+1,j)=\displaystyle \left( \sum_{k=j-1}^i dp(k,j-1) \right)*num(i)dp(i+1,j)=⎝⎛k=j−1∑idp(k,j−1)⎠⎞∗num(i),可通过记录中间量将时间复原创 2021-07-31 19:39:40 · 99 阅读 · 0 评论 -
P4644 [USACO05DEC]Cleaning Shifts S(线段树维护DP)
将目标区间[m,e]转换为[1,e-m+1],同时转换每个奶牛的工作区间。dp[i]表示覆盖区间[1,i]所需最小代价,dp[T2]=min(dp[i]+s),T1-1<=i<=T2-1。状态转移方程涉及区间查询最小值,因此可以丢进线段树维护。时间复杂度O(ne)降至O(nloge)。初始将cow按T2从小到大排序,segmenttree[0,0]=0。#include <iostream>#include <cstdio>#include <alg.原创 2021-07-28 11:56:05 · 211 阅读 · 0 评论 -
P1433 吃奶酪
题意:房间里放着 nn 块奶酪。一只小老鼠要把它们都吃掉,问至少要跑多少距离?老鼠一开始在 (0,0)(0,0) 点处。1<=n<=15,|x|,|y|<=200。2^15<40000,考虑对路径状态压缩。dp[i][j]表示最后一个到达的点为i,走完状态j的最短路径,dp[i][j]=min{dp[k][j-2^(i-1)]}。tips:不要弄错状态转移方程,写之前多考虑两个状态间转移的合法性与前置状态是否完成转移(考虑转移的正确性)。#include<iost.原创 2021-06-02 12:14:53 · 173 阅读 · 0 评论 -
UVA116 单向TSP Unidirectional TSP
注意写法,细节的处理方式,递推的方向。#include <iostream>#include <cstdio>#include <algorithm>using namespace std;const int inf =0x3f3f3f3f;int m,n,ll,rr;int g[15][105],d[15][105],c[3]={-1,0,1},pre[15][105],pos[4];int main(){// freopen("1.txt.原创 2021-05-15 00:39:08 · 114 阅读 · 0 评论 -
UVA1412 基金管理 Fund Management
状态压缩,一个状态是一个九进制数,vector<vector >states对状态编号(编号>状态),map<vector,int>id(状态>编号)紫书的代码里用一个vector< int >表示状态,巧妙。预处理编号为状态s下对股票i的进行买卖操作后得到的状态编号。#include <iostream>#include <cstdio>#include <vector>#include <map>.原创 2021-05-13 01:50:34 · 106 阅读 · 0 评论 -
UVA1252 20个问题 Twenty Questions
与校长的烦恼高度相似,多集合组成状态,集合用压缩的状态表示。d(s,a)表示询问的集合为s,目标物体特征为a时最少还需要询问几次。枚举下一次所有可能的询问,假设下一询问为k,则询问次数为max(d(s+{k},a),d(s+{k},a+{k}))+1,d(s,a)取所有可能的k中的最小值。边界条件为只有一个物品满足a中所有特征且不满足s-a中特征时d(s,a)=0。注意:在计算过程中存在目标不在所有物品中(因为目标是假设的),没有物品满足a中所有特征且不满足s-a中特征时d(s,0)=0。可预处理优化.原创 2021-05-11 00:58:49 · 256 阅读 · 2 评论 -
UVA10817 校长的烦恼 Headmaster‘s Headache
题意:校长的烦恼 Headmaster’s Headaches很小,不难想到用状态压缩处理。但是我对状态压缩的应用还是固守在了处理棋盘上,一开始想的是把每门学科用两位二进数表示,但是没法做状态转移。正解:用两个二进数表示当前状态,第一个数s1表示恰有一个人教的学科集合(某一位为0表示不在集合中,某一位为1表示在集合中),另一个数表示至少有两个人教的学科的集合,d(i,s1,s2)表示已经考虑了前i-1个人时(前i-1人聘用情况确定即s1s2确定,后面人的聘用情况任意)此状态下的最小花费,答案为d(1,.原创 2021-05-10 19:41:23 · 105 阅读 · 0 评论 -
NOIP2006能量项链(区间DP)
典型的区间DP,f[i][j]表示(i~j) 区间合并成一个珠子得到的最大值,f[i][j]=max(f[i][k]+f[k+1][j]+a[i]+a[k+1]+a[j+1]),其中k∈[i,j-1],表示区间(i~k)与区间(k+1 ~ j)合并。#include<iostream>#include<cstdio>#include<cmath>using namespace std;int n,a[505],f[305][305],ans;int mai.原创 2020-12-31 12:09:56 · 108 阅读 · 0 评论 -
CF11D A Simple Task
#include <iostream>#include <cstdio>#include <cstring>using namespace std;long long n,m,cnt,last[25],x,y,ans,dp[600005][25];struct edge{ int v,next;}e[1005];inline void add(int u,int v){ e[++cnt].v=v; e[cnt].next=last[原创 2020-11-28 22:25:17 · 105 阅读 · 0 评论 -
CF16E Fish
有n条鱼,每天会有两条鱼相遇,每天任意两条鱼相遇的概率一样,给出i,j相遇时i吃掉j的概率和j吃掉i的概率,最后池塘中只会留下一条鱼,求最后池塘中留下的每条鱼的概率。n<=18当池塘还剩下cnt 条鱼时,选出还在池塘中的鱼i,j的概率为2/cnt/(cnt-1),i吃掉j的概率为a[i][j];可以考虑对池塘进行状态压缩,n条鱼的池塘看成n为二进制数,设当前状态为s,s中的i吃掉了j,则状态变为s^(1<<(j-1)),因此状态转移方程为f [s^(1<<(j-1))]=.原创 2020-11-22 01:56:18 · 117 阅读 · 0 评论 -
UVA11766 Racing Car Computer
解法巧妙的一道题!题意:n辆赛车,n条信息,第i条信息告诉你编号为i的车前面与后面分别有多少量车,求最少有多少条信息是错误的。将问题转换一下,等价于最多有多少条信息是对的。考虑每条信息意味着什么:知道了前后有多少量车,也就知道了这辆车的排名区间以及有多少量车与它并排!每一条合法(对它自己而言)的信息可以确定一个排名区间,如a=1,b=2,n=5,它的排名区间就是[2,3],如果两条信息得出的排名区间有重叠,那么它们就是冲突的,反之不冲突。我们可以做这样一个处理:每得出一个区间[i,j],就给cn.原创 2020-11-03 23:33:49 · 83 阅读 · 0 评论 -
关于刷表法
for(长度)for(左界)通过左界和长度定位右界;每次可以看成拿一段区间在数轴上平移,每一轮平移可以更新出这一区间长度+1的答案,然后下一轮拿区间长度+1的区间继续扫。原创 2020-10-15 23:25:38 · 483 阅读 · 0 评论 -
UVA10003 切木棍 Cutting Sticks
d(i,j)表示将第i个切割点到第j个切割点分成i-j段所花费的最小代价,d(i,j)=min(d(i,k)+d(k,j)+a(i)-a(j)),为什么可以这样设置,因为我们考虑(i,j)的最小切割代价的时候,只有第一刀的代价是可以直接知道的,以此可以作为状态间转移的“跳板”。#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>using namespace std;原创 2020-10-07 20:55:46 · 136 阅读 · 0 评论 -
树的最大独立集(UVA1220)Party at Hali-Bula
对于一颗n个结点的无根树,选出尽量多的结点,使得任何两个结点均不相邻(称为最大独立集),然后输入n-1条无向边,输出一个最大独立集(如果有多解输出任意一组)。任选一个根r,d(i)表示以i为根结点的子树的最大独立集大小,结点i有两种决策,选与不选,如果不选i,问题变成了所有儿子的值相加,如果选i,问题变成了所有孙子的值相加再加1,即d(i)=max(1+Σd(j),Σd(k));j为i的孙子(gs[i]),k为i的儿子(s[i])。实现时可以从s[i]与gs(i)的元素去找i,即当计算出一个d(i)后原创 2020-10-08 19:44:33 · 242 阅读 · 0 评论 -
UVA1628送披萨
依旧使用具有“累加”意义的状态,与修长城不同的是,路过某点时不一定要累加改点的“权值”,但是每一次移动对今后所有累加的点的“权值”的影响是相同的,为此可以增加一维cnt,d(i,j,cnt,p)表示i~j的决策已经确定时,当前在p(i或者j),从(1 ~ i-1)与(j+1)中选取cnt个所能得到的“最大收益”,状态的转移可以通过枚举第cnt中的第一个累加的点实现,假设选取的点为x,则代表x+1 ~ i-1或j+1 ~ x-1的点舍弃 ,原因在于“在任意时刻,送餐的人已经考虑过的(送了或者决定放弃订单).原创 2020-10-21 20:38:14 · 211 阅读 · 0 评论