![](https://img-blog.csdnimg.cn/20201014180756922.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
dp
我的妹妹syf
我的妹妹不可能那么胖
展开
-
codeforces 442D - Adam and Tree
题目大意:给一棵树上的每条边染色,每种颜色只能用一次,一次染色树上的一条链。问(从根到所有节点经过的颜色的最大值)的最小值是多少。树是通过每次加一个点得到的,问每次加点之后的最小值是多少。点数不难发现,答案肯定是小于等于直接树剖的答案,也就是log当前点数。显然能想到dp:用f[i]表示处理i的所有子树和i所需的最小颜色。如果正常染色的话,我们会尝试把f值最小的两棵子树和i原创 2017-07-12 11:45:51 · 1144 阅读 · 0 评论 -
BZOJ 1569: [JSOI2008]Blue Mary的职员分配
随便记一下状态,然后再随便转移一下,没了。Tips:1.第三天招来的人第四天才能工作2.当天赚的钱可以用来招人#include<bits/stdc++.h>using namespace std;int dp[41][101][41][4][2];int n,x,y,z,A,B;int bes=1008610086;int dfs(int rs,int jq,int sy,i...原创 2018-04-25 21:39:32 · 171 阅读 · 0 评论 -
bzoj 1560: [JSOI2009]火星藏宝图
考虑DP,朴素的DP是N^2发现如果有路径A->B,B->C,A->C,那么一定是A->B,然后再B->C也就是说,对某个点有影响的点位于一个凸包上。由于坐标范围只有[1,M],所以复杂度应该是O(NM),实际上可以通过此题。似乎转移的斜率还有单调性,但是懒得再推了。#include<bits/stdc++.h>#define M 1010#defin...原创 2018-04-24 21:06:17 · 138 阅读 · 0 评论 -
BZOJ 1302 ZOJ 2271
简单概率题,新加SPJ,注意n可能是偶数=。=#include<bits/stdc++.h>#define N 110using namespace std;int n;double dp[N][N][N];int main(){ while(scanf("%d",&n)!=-1){ for(int i=0;i<=n;i++) ...原创 2018-04-17 15:04:04 · 195 阅读 · 0 评论 -
Atcoder Grand Contest 013D piling Up
题目大意:初始时有i个红球(i∈[0,n])和n-i个蓝球。进行m次操作,每次先任意选出一个球,然后再放入一个蓝球和一个红球,再任意选出一个球。问选出的球的序列有多少种可能?n,m∈[1,3000]首先,我们用i表示当前红球的数量:不难发现,如果我们将两次取球合并,那么每次操作必然是以下四种:1、i>=1时,可以取出两个红球,i-=12、i>=1时,可以先取出一个红球,再取出一原创 2017-10-03 18:54:16 · 235 阅读 · 0 评论 -
NWERC 2015B/bzoj 4426 Better Productivity
#include#define N 210using namespace std;struct Node{int x,y;}a[N],b[N],c[N];int dp[N][N];int n,p,B,C;inline bool cmp1(Node a,Node b){ if(a.x!=b.x) return a.x<b.x; return a.y<b.y;}inline boo原创 2017-10-02 18:47:32 · 341 阅读 · 0 评论 -
4428: [Nwerc2015]Debugging调试
#include#define N 1000100using namespace std;long long f[N],x,y;int n;long long dfs(int p){ if(f[p]!=-1) return f[p]; if(p==1) return f[p]=0; f[p]=x+y*(p-1); for(int i=2;i<p;i=(p-原创 2017-10-01 20:05:42 · 282 阅读 · 0 评论 -
codeforces 571B
#include#define N 300100using namespace std;inline int read(){ int f=0,a=0;char ch=getchar(); while(ch'9'){if(ch=='-') f=1;ch=getchar();} while(ch='0') a=a*10+ch-'0',ch=getchar(); if(f) return原创 2017-10-01 20:00:01 · 242 阅读 · 0 评论 -
codeforces 115D
#include#define N 2010using namespace std;const int MOD=1e6+3;int n;string s;int dp[N][N];int sum[N][N];int w[N];int z[N];int main(){ cin>>s; int siz=s.size(); int len=0; if(s[0]=='/'||s原创 2017-10-01 19:58:26 · 349 阅读 · 0 评论 -
洛谷P2899 [USACO08JAN]手机网络Cell Phone Network
#include#define N 100100using namespace std;const int INF=1008610086;int A[N],B[N],C[N];int beg[N],to[N],nex[N];int n,len;inline void Add(int a,int b){ nex[++len]=beg[a],beg[a]=len,to[len]=原创 2017-10-17 19:05:14 · 671 阅读 · 0 评论 -
51Nod 1055 最长等差数列问题
1055 最长等差数列基准时间限制:2 秒 空间限制:262144 KB 分值: 80 难度:5级算法题 收藏 关注N个不同的正整数,找出由这些数组成的最长的等差数列。例如:1 3 5 6 8 9 10 12 13 14等差子数列包括(仅包括两项的不列举)1 3 51 5 9 133 6 9 123原创 2017-07-09 11:25:06 · 366 阅读 · 1 评论 -
UVA 1084 deer-proof fence
题目大意:N个点的半径为M的圆,求最小周长的方案使他们都被包含在所画的图形中(可以相隔)。因为N那么可以得到方程f[i]=min(f[j]+f[i^j]),j为i的所有子集。先处理g[i]表示i组成一个图形的周长,周长是i中所有点的凸包总长+2πM。那么问题就迎刃而解了。附代码(小学dalao好厉害):#includeusing namespace std;struct N原创 2017-07-09 10:26:31 · 371 阅读 · 0 评论 -
codeforces 590D
题目大意:N个数,最多S次交换次数,每次能交换相邻两个数,问前k个数的最小总和是多少。比较简单的dp,一开始想复杂了。用f [ i ] [ j ]表示考虑了i个数,用了j次交换的情况。发现有方程f[i+1][j+l-i-1]=min(f[i+1][j+l-i-1],f[i][j]+a[l]);如果我们先从小到大枚举l(从哪里交换过来),就避免了后效性。接下来从大到小枚举i,原创 2017-07-08 09:59:45 · 328 阅读 · 0 评论 -
ZOJ 3161 Damn Couple
简单dp,就是题目不太好懂N个人,M组关系,每次选一种关系,如果两个人相邻,则任意删除其中一个,否则不变。问最坏情况下最多能剩多少人?发现不相邻的就没有影响了,那么只考虑相邻的。发现相邻的会组成一些连通块,每个连通块的最优结果可以DP:f[i]=max ( min ( f [ j ]+f [ i - j - 1] , f [ j - 1 ] + f [ i - j ] ) )附代原创 2017-07-06 16:11:24 · 364 阅读 · 0 评论 -
codeforces 505C Mr. Kitayuta, the Treasure Hunter
比较简单的题,然而我老毛病又犯了,调错的时候容易上头= =用dp[i][j]表示走到i,上一步走了j。但是直接做显然又T又M。由于速度大于零,所以设最大变化量为x,显然有(x+1)*x附代码#include#define N 30010using namespace std;int dp[N*2][1010];int va[N*2];int n,d;int main(){ m原创 2017-07-06 13:49:14 · 318 阅读 · 0 评论 -
codeforces 482C Game with Strings
真是一道神题=。=做了一上午题目大意:给你N个等长字符串(N因为长度小于等于20,所以可以比较显然地想到状压DP。接下来YY一下转移方程、首先我们需要知道,按照当前猜的位置,能否得到答案。那么用一个数组f[i]表示猜的状态是f[i]时,还没有猜出的字符串的状态、我们可以先找到哪些操作不能区分两个字符串。那么我们枚举两个字符串的序号i,j,那么对于每一位s[j][place]==s[原创 2017-07-04 15:56:50 · 385 阅读 · 0 评论 -
51Nod 1020 逆序排列
在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。如2 4 3 1中,2 1,4 3,4 1,3 1是逆序,逆序数是4。1-n的全排列中,逆序数最小为0(正序),最大为n*(n-1) / 2(倒序)给出2个数n和k,求1-n的全排列中,逆序数为k的排列有多少种?例如:n = 4原创 2017-07-03 09:45:23 · 335 阅读 · 0 评论 -
bzoj 1820: [JSOI2010]Express Service 快递服务
直接写状态的话,可以用dp[i][j][k][l]表示位置在j,k,l,当前完成的是第i个任务。发现j,k,l一定有一个和p[i]相同,可以再减掉一维。这样的话复杂度就是m^2n的。但是空间只有64M,所以还需要再滚动数组压掉一维。#include<bits/stdc++.h>#define N 1010#define M 210using namespace std;int ...原创 2018-04-26 19:19:10 · 276 阅读 · 0 评论