dp

leetcode279 完全平方数

眉间皱痕 提交于 2019-12-06 20:24:29
class Solution { public: int numSquares(int n) { //初始化vector<int> dp[i]=i i=[0,n]; //状态转移方程 dp[i]=min(dp[i],dp[i-j*j]+1) i-j*j>=0 && j=0, j++; //time O(nsqrt(n)) space O(1); vector<int> dp; for(int i=0;i<=n;i++){ dp.push_back(i); } for(int i=1;i<=n;i++){ for(int j=1;i-j*j>=0;j++){ dp[i]=min(dp[i],dp[i-j*j]+1); } } return dp[n]; } }; 来源: https://www.cnblogs.com/joelwang/p/11997420.html

AGC022E Median Replace

北城以北 提交于 2019-12-06 20:18:28
题意 给出一个长度为奇数 \(n\) 的残缺 01 串,问有多少种补全方法,每次将连续三个位替换为它们的中位数后,能有一种方案使它变为 1 。 \(n \le 3*10^5\) 思路 左边表示栈顶。 将操作简化为:将 000 变为 0 ;将 111 变为 1 ;删掉相邻的 01 或 10 . 考虑这些操作的优先级,显然是每次有 000 就执行,没有就执行 01 或 10 ,都没有再执行 111 。同类内部的顺序并不影响结果。 现在考虑用栈维护,从左往右加入串中字符,如果加入了 1 ,那么栈顶是 0 便可弹掉; 如果加入了 0 ,由于 000 优先于其他,栈顶是 1 也暂时不操作,最后再考虑 10 和 111 操作。这样栈的形态尝试一下,就可以得出如下列举的,只有这么几种。 注意当 \(1\) 的个数 \(\ge 2\) 时,肯定是可行的,可以等价到两个的情况。 因为最后只要有两个 \(1\) 或者 1 。加起来,输出就可以了 我的状态是这样的: - , 0 , 1 , 00 , 01 , 11 , 001 , 011 , 0011 ; #include <bits/stdc++.h> const int N=300005,mu=1000000007; const int tran[2][N]={{1,3,4,1,6,7,4,8,7},{2,0,5,1,2,5,4,5,7}};

HDU - 4352 - XHXJ's LIS(数位DP)

我只是一个虾纸丫 提交于 2019-12-06 15:23:38
链接: https://vjudge.net/problem/HDU-4352 题意: a 到 b中一个数组成递增子序列长度等于k的数的个数 思路: 因为只有10个数,使用二进制维护一个递增序列,每次更新在注释写了。 然后正常的数位DP, Dp(i, j, k),i是位置,j是当前的递增状态,k是长度。 考虑一下前缀0,重置状态 代码: #include<bits/stdc++.h> using namespace std; typedef long long LL; const int MOD = 1e9+7; const int MAXN = 1e6+10; LL F[30][1<<10][11]; int dig[30]; LL a, b; int k; int Upd(int x, int s) { //x表示当前值,s表示递增序列 for (int i = x;i < 10;i++) { if (s & (1<<i)) return (s ^ (1 << i)) | (1 << x);//找到一个比当前值大的,换成较小的 } return s | (1 << x); } int Len(int x) { int cnt = 0; while(x) { if (x&1) cnt++; x >>= 1; } return cnt; } LL Dfs(int pos, int

[LOJ#2743][DP]「JOI Open 2016」摩天大楼

折月煮酒 提交于 2019-12-06 09:38:17
题目传送门 DP 经典题 考虑从小到大把数加入排列内 如下图( \(A\) 已经经过排序): 我们考虑如上,在 \(i\) ( \(A_i\) )不断增大的过程中,维护上面直线 \(y=A_i\) 之下的部分的长度之和 于是我们定义 DP : \(f[i][j][k][h]\) 表示插入了前 \(i\) 个数,分成 \(j\) 段, \(y=A_i\) 之下的部分长度之和为 \(k\) ,并且选出了 \(k\) ( \(0/1/2\) )个边界(第 \(1\) 个或第 \(n\) 个)的方案数 注意这个 DP 中我们只需要保证每段是否在边界以及相邻两段之间有空位即可,不关心每段的实际位置 不难发现,从 \(f[i][j][k][h]\) 转移到 \(f[i+1]\) , \(k\) 的增量是固定的,即对于每个段的两端,将直线从 \(y=A_i\) 移到 \(y=A_{i+1}\) 时每端都会多出 \(A_{i+1}-A_i\) 的长度(边界除外),于是 \(f[i][j][k][h]\) 转移到 \(f[i+1]\) 时 \(k\) 的增量为 \((A_{i+1}-A_i)\times(2j-h)\) ,设其为 \(w\) 。下面讨论几种情况进行转移: (1)新建一段,这一段可以放在边界除外的任意 \(j+1\) 个空隙内: \[f[i+1][j+1][w][h]+=f[i][j]

PKUWC2018题解

孤人 提交于 2019-12-06 06:27:43
按照 \(\texttt{loj}\) 的顺序写的 「PKUWC2018」Minimax 比较神仙的线段树合并,可能是我对于线段树合并还了解的不够透彻吧. 很显然可以对于每一个点的取值离散化后 \(dp\) 概率对吧. \[ \begin{align} dp_{u,i}&=dp_{l,i}\times(\sum_{j=1}^{i-1}dp_{r,j}*p+\sum_{j=i+1}^{tot}dp_{r,j}*(1-p))\\ &+dp_{r,i}\times(\sum_{j=1}^{i-1}dp_{l,j}*p+\sum_{j=i+1}^{tot}dp_{l,j}*(1-p)) \end{align} \] 这个东西的转移需要一个前缀和一个后缀和. 然后线段树合并的套路就是对于这个东西在合并左右子树线段树的时候记录一个和.如果要返回直接打乘法标记上去. 很清奇 代码 来源: https://www.cnblogs.com/fexuile/p/11965452.html

Balanced Numbers SPOJ - BALNUM

北城以北 提交于 2019-12-05 17:33:38
代码+注释 1 //我感觉这道题最扯的就是我因为输入而TLE了半天,懵逼死了,想破脑袋也没想到因为输入TLE了半天 2 //题意:求区间内数字满足“奇数各数出现偶数次,偶数各数出现奇数次”的数字的个数。 3 //题解: 4 //dp[x][y]表示长度为x的时候0~9各出现的状态情况,因为可能有未出现的情况,如果这个y用二进制 5 //保存的话那么未出现的偶数可能会因为0而出现误判,所以应该多一个状态,就用三进制。0表示未出现, 6 //1表示出现了奇数次,2表示出现了偶数次。 7 //就是一道状压+数位dp,和XHXJ's LIS HDU - 4352 很相似 8 //XHXJ's LIS HDU - 4352(这个是状压成二进制+dp):https://www.cnblogs.com/kongbursi-2292702937/p/11934243.html 9 10 #include<stdio.h> 11 #include<string.h> 12 #include<algorithm> 13 #include<iostream> 14 using namespace std; 15 const int maxn=20; 16 const int N=1<<10; 17 typedef long long ll; 18 ll v[maxn],dp[maxn][60000],w

关于DP与DFS

无人久伴 提交于 2019-12-05 09:55:12
在二维矩阵上的DFS只有两个方向时,沿着矩形某一个角的方向时,有些问题可以转化为DP来求,同时,这种情况一般无法用DFS来求,因为n与m的值特别大 比如求出从一个角到另一个角的路径有几种 ---- 下面是求出从左上角到右下角的路径种类 dp[0][1]=1 for(int I=1;i<=n;i++){ for(int j=1;j<=m;j++){ dp[i][j]=dp[i-1][j]+dp[i][j-1]; } } 初始化的时候注意只初始化起始点即可,不然会和后面的条件冲突 (牛客小白赛就是因为这个原因wa了QAQ) 题 传送门 #include <iostream> #include <cstdio> #include <cstring> #define ll long long using namespace std; const int maxn = 3e3+5; const int inf = 0x3f3f3f3f; const int mod = 2333; int read(){ int x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();} return f*x; }

网络编程-upd\\Socket接收发送

橙三吉。 提交于 2019-12-04 19:53:22
import java.io.*; import java.net.*; public class first { public static void main(String[] args) { // TODO Auto-generated method stub MySend ms = new MySend(); MyRece mr = new MyRece(); Thread th1 = new Thread(ms); Thread th2 = new Thread(mr); th1.start(); th2.start(); } } class MySend implements Runnable { public void run() { DatagramSocket ds = null; try { ds = new DatagramSocket(8888); } catch (SocketException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 2 确定数据 、 封装成数据包 byte[] data = "udp ge men lai le ".getBytes(); DatagramPacket dp = null; try { dp = new

leetcode 44 通配符匹配(dp)

人走茶凉 提交于 2019-12-04 17:29:38
思路: 思路一: 利用两个指针进行遍历。 在代码里解释. 时间复杂度为:O(mn)O(mn)O(mn) 思路二: 动态规划 dp[i][j]表示s到i位置,p到j位置是否匹配! 初始化: dp[0][0]:什么都没有,所以为true 第一行dp[0][j],换句话说,s为空,与p匹配,所以只要p开始为*才为true 第一列dp[i][0],当然全部为False 动态方程: 如果(s[i] == p[j] || p[j] == "?") && dp[i-1][j-1] ,有dp[i][j] = true 如果p[j] == "*" && (dp[i-1][j] = true || dp[i][j-1] = true) 有dp[i][j] = true ​ note: ​ dp[i][j-1],表示*代表是空字符,例如ab,ab* ​ dp[i-1][j],表示*代表非空任何字符,例如abcd,ab* ​ class Solution { public boolean isMatch(String s, String p) { int sn = s.length(); int pn = p.length(); int i = 0; int j = 0; int start = -1; int match = 0; while (i < sn) { if (j < pn && (s

UVA 10900 So you want to be a 2n-aire? (概率dp)

自闭症网瘾萝莉.ら 提交于 2019-12-04 13:56:30
题意:玩家初始的金额为1;给出n,表示有n道题目;t表示说答对一道题目的概率在t到1之间均匀分布。    每次面对一道题,可以选择结束游戏,获得当前奖金;或者回答下一道问题,答对的话奖金翻倍,答错的话结束游戏没有奖金,求玩家使用最优策略赢的奖金的期望值的最大值。 题解:遇见第(i+1)个题目的时候有两种选择:结束这个题,获得2^i的钱;回答这个题目,答对就获得2^(i+1)的钱    因此设dp[i]表示答对第i个题,面对第(i+1)个题可以获得的期望钱数,则dp[i]=2^i * 不去回答这个题的概率 + dp[i+1] * 回答这个题的概率 * 答对这个题的概率    答对这个题的概率 p0=max(t,(2^i)/dp[i+1])    (2^i)/dp[i+1]表示回答第 i+1 个题需要这么大的概率才能获得更大的价值;max表示如果t大于这个概率,则我们就只能选择t(注意题目给定的概率为范围,最小的概率为t)     回答这个题的概率 p1=(1-p0)/(1-t)(注意t=1的情况);就是说给定的概率如果太小,那么 就有可能在某些情况下不去回答这个题 #include< set > #include <map> #include <queue> #include <stack> #include <cmath> #include <vector> #include <