Online Judge:未知 Label:Dp+滚动+前缀和优化 题目描述 有一个长度为1*n的棋盘,有一些棋子在上面,标记为L和R. 每次操作可以把标记为L的棋子,向左移动一格,把标记为R的棋子,向右移动一格,前提条件是目标格子为空.结果任意多次操作之后,棋盘会有多少种不同的状态? 输入 第一行一个字符串,包含'L','R','.'. 输出 输出所有不同的棋盘状态,对1e9+7 求余. 样例 Input R.. R.L ...R..L..L R..L......LLR.RRL..RR....…
最开始想的暴力DP是把天数作为一个维度所以怎么都没有办法优化,矩阵快速幂也是$O(n^3)$会爆炸. 但是没有想到另一个转移方程:定义$f[i][j]$表示每天都有值的$i$天,共消费出总值$j$的方案数.然后答案就是. 所以每次维护前缀和就可以$O(1)$转移了. 注意前缀和的初值. #include<bits/stdc++.h> #define LL long long #define mod 998244353 using namespace std; int n, m; LL d; L…
[题目大意] 给定n个数和两个长度为n*5的序列,两个序列中的数均有1..n组成,且1..n中每个数恰好出现5次,求两个序列的LCS. [思路] 预处理每个数字在a[i]中出现的五个位置.f[i]示以a[i]为末尾的最长公共子串(*这样就可以避免讨论交叉). 依次处理b[i],对于每个b[i]找到a[i]中的五个位置转移,用nowp表示,转移很简单:f[nowp]=max(f[nowp],query(nowp-1)+1),这里需要维护前缀最大值. 才知道前缀最大值可以用BIT来维护. 不过要注意…
题目 有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块. 所有油漆刚好足够涂满所有木块,即c1+c2+-+ck=n.相邻两个木块涂相同色显得很难看,所以你希望统计任意两 个相邻木块颜色不同的着色方案. 输入格式 第一行为一个正整数k,第二行包含k个整数c1, c2, - , ck. 输出格式 输出一个整数,即方案总数模1,000,000,007的结果. 输入样例 3 1 2 3 输出样例 10 提示 100%的数据满足:1 <= k <=…
Dividing Time Limit: 1000MS Memory Limit: 10000K Description Marsha and Bill own a collection of marbles. They want to split the collection among themselves so that both receive an equal share of the marbles. This would be easy if all the marbles had…
862. 二进制数01串 ★   输入文件:kimbits.in   输出文件:kimbits.out   简单对比 时间限制:1 s   内存限制:128 MB USACO/kimbits(译 by !Starliu ) 描述 考虑排好序的N(N<=31)位二进制数. 你会发现,这很有趣.因为他们是排列好的,而且包含所有可能的长度为N且含有1的个数小于等于L(L<=N)的数. 你的任务是输出第I(1<=I<=长度为N的二进制数的个数)大的,长度为N,且含有1的个数小于等于L的那个…
题目链接 http://codeforces.com/problemset/problem/597/C 题意 给出一个n 一个 k 求 n 个数中 长度为k的上升子序列 有多少个 思路 刚开始就是想用dp 复杂度 大概是 O(n ^ 2 * k) T了 但是 思路还是一样的 只是用树状数组 优化了一下 第三层循环 dp[i][j] 表示 第 i 个数 长度为 j 时 那么 dp[i][j] 的状态转移就是 ∑(arr[i] > arr[k] ? : dp[k][j - 1] ) AC代码 #in…
思路: DP[ i ] 代表以 i 结尾的方案数. dp[i] += sum[i] - sum[j - 1] != 0 ? dp[j] : 0 ; 对于100%的数据,满足1<=N<=105, |Ai|<=100 n 1e5呀,两层for,GG; 利用树状数组维护sum[i],存的是以sum[i]的方案数 , 那么每次加上当前所有的方案,减去sum[i]的方案,就好了. 这里还有一个小问题就是 |sum[i]|<=1e7,所以先离散化一下就好了. 把当前所有前缀和的方案数加起来..…
题意: 给你n个任务,每个任务有一个起始时间,持续时间,一个权值: 问你怎么分配得到最大值 思路: 数据好大..百度了一发意识到自己好菜啊!背包的特性. dp[i]代表前 i 个能构成的最大值. 对于每个任务看成一个背包,背包取的点是固定的 背包取的话肯定是离他开始时间最近的那个点,dp[i]=dp[k(结束时间最靠近他的起始时间的点)]+w[i]; 不取的话dp[i]=dp[i-1]; #include<bits/stdc++.h> using namespace std; typedef…
题意: 有一个k面的骰子,然后问你n个骰子朝上的面数字之和=s的方案: 思路: dp[i][j] 代表 前 i 个骰子组成 j 有多少种方案: 显然 dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j - 2] + ... + dp[i - 1][j - k]; 我们算 dp[i][j] 的时候,需要dp[i-1] 的前缀和已经打出来了 我们求dp[i][j] 的时候,要求出 dp[i][j] 的前缀和,提供给求 i+1 的时候使用: 还有第二种方法:wonter…
还是满水的一道题目吧...这个一看肯定要搜索了..然后又是这么DP,那就是记忆化搜索了...走K步,下一步要比他多...很好写啊/// #include<iostream> #include<cstdio> #include<math.h> #include<queue> #include<map> #include<stdlib.h> #include<string> #include<string.h> #…
简单粗暴的dp应该是把馅饼按时间排序然后设f[i]为i接到馅饼能获得的最大代价,转移是f[i]=max(f[j])+v[i],t[j]<=t[i],2t[i]-2t[j]>=abs(p[i]-p[j]) 后面这个条件就很麻烦,我们分情况讨论拆成两个,也就是当p[i]>p[j],满足2t[i]-p[i]>=2t[j]-p[j],和当p[i]<=p[j],满足2t[i]+p[i]>=2t[j]+p[j],然后注意到,因为t[j]<=t[i],所以满足2t[i]-p[i…
好像是高斯消元解互相推(?)的dp的例子 首先考虑dp,设f[i][j]为一人在i一人在j的概率,点i答案显然就是f[i][i]: 然后根据题意,得到转移是 \[ f[i][j]=f[i][j]*p_i*p_j+\sum_{edge(x,i)\in E}f[x][j]*p_j*\frac{1-p[x]}{d[x]}+\sum_{edge(y,j)\in E}f[i][y]*p_i*\frac{1-p[y]}{d[y]}++\sum_{edge(x,i)\in E,edge(y,j)\in E}f…
题意: 有b个blocks,每个blocks都有n个相同的0~9的数字,如果从第一个block选1,从第二个block选2,那么就构成12,问对于给定的n,b有多少种构成方案使最后模x的余数为k. 分析: dp+矩阵快速幂. 假如现在的数是m,模x余数是n,那么再从下一个block中选一个数a,a模x余数为b,那么新的数的余数就为(m∗10+a)%x,也就是(n∗10+b)%x,所以实际上我们只需要直接对余数进行操作.容易得到状态转移方程,其中dp[i][j]表示从第i个block中选择一个数后…
算是比较经典的高斯消元应用了 设f[i]为i点答案,那么dp转移为f[u]=Σf[v]*(1-p/q)/d[v],意思是在u点爆炸可以从与u相连的v点转移过来 然后因为所有f都是未知数,高斯消元即可(记得输出大难的时候除以总概率和) #include<iostream> #include<cstdio> using namespace std; const int N=305; int n,m,d[N],h[N],cnt; double a[N][N],f[N],p,q,ans;…
DP例题较多,可以根据自己需求食用~ update:下翻有状压DP入门讲解,也只有讲解了(逃~ DP的实质,就是状态的枚举. 一般用DP解决的问题,都是求计数或最优问题,所以这类问题,我们也可以用搜索来解决. 但是,之所以出现DP,就是因为在有些情况下,搜索不能以较高的效率求解,题目也不需要记录过程,而DP是直接记录答案,不记录过程,效率较高,所以深受广大OIer的唾弃喜爱. 所以写DP的难点就在如何表示每一个状态并利用它快速推出我们想得到的答案. 让我们通过一些毒瘤经典例题来练习DP吧awa…
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5586 Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 677    Accepted Submission(s): 358 Problem Description There is a number sequence A1,A2...…
第一问明显就是用b[i]=a[i]-i来做最长不下降子序列 然后第二问,对于一对f[i]=f[j]+1的(i,j),中间的数一定要改的,并且是等于b[i]或者b[j],我不会证,然后因为是随机数据,所以直接枚举断点用前缀和更新答案即可 证明见http://ydcydcy1.blog.163.com/blog/static/216089040201392851210681/ #include<iostream> #include<cstdio> #include<cstring…
注意到周期234的lcm只有12,也就是以12为周期,可以走的状态是一样的 所以先预处理出这12个状态的转移矩阵,乘起来,然后矩阵快速幂优化转移k/12次,然后剩下的次数暴力转移即可 #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int mod=10000; int n,m,s,t,k,x,y,nf,T,w[60]; struct jz { int a[6…
矩阵乘法一般不满足交换律!!所以快速幂里需要注意乘的顺序!! 其实不难,设f[i]为i的答案,那么f[i]=(f[i-1]w[i]+i)%mod,w[i]是1e(i的位数),这个很容易写成矩阵的形式,然后按每一位分别矩阵快速幂即可 矩阵: f[i-1] w[i] 1 1 f[i] i-1 0 1 1 = i 1 0 0 1 1 #include<iostream> #include<cstdio> using namespace std; long long n,mod,t; lo…
把长度转成右端点,按右端点排升序,f[i]=max(f[j]&&r[j]<l[i]),因为r是有序的,所以可以直接二分出能转移的区间(1,w),然后用树状数组维护区间f的max,每次转移的时候直接从树状数组上查询前缀max即可,然后把更新出来的f[i]update进树状数组 #include<iostream> #include<cstdio> #include<algorithm> using namespace std; const int N…
虽然还是悬线法,但是这道题可不能轻易地套模板了,而是要换一种思路,横着扫一遍,竖着扫一遍,时间复杂度依旧是O(n^2),然而空间复杂度有一定的优化 如果用原来的方法,显然时间空间都会炸(如果你想用map我也没办法...时间换空间?) #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<map> #define st short int…
正题 题目链接:https://www.luogu.com.cn/problem/P6847 题目大意 \(n\)个点的一棵树上,每个时刻可以割掉一些边,一些节点上有果实表示如果在\(d_i\)时刻这个点恰好不与\(1\)联通,那么就可以获得\(w_i\)的价值. \(1\leq n,k\leq 10^5\) 解题思路 设\(f_{x,i}\)表示节点\(x\)在时刻\(i\)之前割掉时的最大权值那么相当与在儿子里面选一个最大的\(f_{y,j}(j\leq i)\)合并上来. 这是一个很经典的…
1260: [CQOI2007]涂色paint Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 893  Solved: 540[Submit][Status][Discuss] Description 假设你有一条长度为5的木版,初始时没有涂过任何颜色.你希望把它的5个单位长度分别涂上红.绿.蓝.绿.红色,用一个长度为5的字符串表示这个目标:RGBGR. 每次你可以把一段连续的木版涂成一个给定的颜色,后涂的颜色覆盖先涂的颜色.例如第一次把木版涂成R…
题目描述 Flappy Bird 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画面右方的管道缝隙.如果小鸟一不小心撞到了水管或者掉在地上的话,便宣告失败. 为了简化问题,我们对游戏规则进行了简化和改编: 游戏界面是一个长为n ,高为 m 的二维平面,其中有k 个管道(忽略管道的宽度). 小鸟始终在游戏界面内移动.小鸟从游戏界面最左边任意整数高度位置出发,到达游戏界面最右边时,游戏完成. 小鸟每个单位时间沿横坐标方向右移的距离为1 ,竖直移动…
Description 黑白棋(game) [问题描述] 小A和小B又想到了一个新的游戏. 这个游戏是在一个1*n的棋盘上进行的,棋盘上有k个棋子,一半是黑色,一半是白色. 最左边是白色棋子,最右边是黑色棋子,相邻的棋子颜色不同. E 小A可以移动白色棋子,小B可以移动黑色的棋子,他们每次操作可以移动1到d个棋子. 每当移动某一个棋子时,这个棋子不能跨越两边的棋子,当然也不可以出界.当谁不可以操作时,谁就失败了. 小A和小B轮流操作,现在小A先移动,有多少种初始棋子的布局会使他胜利呢? Inpu…
题目:id=2411" target="_blank">poj 2411 Mondriaan's Dream 题意:给出一个n*m的矩阵,让你用1*2的矩阵铺满,然后问你最多由多少种不同的方案. 分析:这是一个比較经典的题目.网上各种牛B写法一大堆.题解也是 我们能够定义状态:dp[i][st]:在第 i 行状态为 st 的时候的最慷慨案数. 然后转移方程:dp[i][st] = sum (dp[i-1][ss]) 即全部的当前行都是由上一行合法的状态转移而来. 而状态…
不错的dp入门题  画出dp矩阵  每个dp[i][j]是由“其上”的状态或是“其左上”的状态转化而来,那我们选对角线和上边进行三角dp推导 #include<stdio.h> #include <iostream> using namespace std; #define MAX 110 int value[MAX][MAX]; int f[MAX][MAX]; int F,V; int main() { // freopen("in.txt","r…
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 用于项目中dp.px.sp之间的转换以及指定缩放值下的转换. 效果图 暂不需要 代码分析 常用的方法是px2dip.dip2px: px2dipRatio.dip2pxRatio方法的应用场景可以理解为一个占满全屏的控件,要求等比例缩放显示到占原屏幕0.95的容器中.此时,可以考虑 使用这两个方法对这个控件的宽度和高度值进行等比例缩放. 使用步骤 一.项目组织结构图 注意事项: 1.导入类文件后需要change包名以及重新imp…
问题一:01背包 题目: [题目描述] 一个旅行者有一个最多能装 M 公斤的背包,现在有 n件物品,它们的重量分别是W1,W2,...,Wn它们的价值分别为C1,C2,...,Cn求旅行者能获得最大总价值. [输入] 第一行:两个整数,MM(背包容量,M≤200)和NN(物品数量,N≤30): 第2..N+12..N+1行:每行二个整数Wi,CiWi,Ci,表示每个物品的重量和价值. [输出] 仅一行,一个数,表示最大总价值. [输入样例] 10 4 2 1 3 3 4 5 7 9 [输出样例]…