nlogn做法,dp[i]表示当前长度为i的最长上升子序列末尾元素的值。

不会写lower_bound(qwq,贴一个以前的好看点的代码

#include<iostream>//使用lower_bound()函数
#include<algorithm>
#include<cstdio>
using namespace std;
int a[],d[],n,len=;
int main()
{
scanf("%d",&n);
for (int i=;i<=n;i++)
scanf("%d",&a[i]);
d[++len]=a[];
for (int i=;i<=n;i++)
if (a[i]>d[len])d[++len]=a[i];
else
{
int x=lower_bound(d+,d+len+,a[i])-d;
d[x]=a[i];
}
printf("%d\n",len);
return ;
}

法一:用度数计算,可以证明最后答案等于选出的k个点的总度数-2*(k-2)-2,表示选择的一条链上去掉两头每个点少减两个度数,两头少减一个度数,就算有分叉也不影响。然后题目转换为求连续的k个点使他们的度数和最小。定义dp[u][k]表示以u为根的子树中选择k个点能获得的最小度数和(包括自己。背包转移。

大佬zyl的代码:

#include<stdio.h>
#include<cstring> const int MAXN = ; inline int min(int a, int b) {
return a < b ? a : b;
} struct Edge {
int to;
Edge *nxt;
} pool[MAXN * ], *head[MAXN], *tail = pool; inline void addEdge(int from, int to) {
Edge *it = tail++;
it -> to = to;
it -> nxt = head[from], head[from] = it;
} int n, k, ans;
int dp[MAXN][MAXN], size[MAXN], w[MAXN]; void dfs(int u, int fa) {
dp[u][] = , dp[u][] = w[u], size[u] = ;
for(Edge *it = head[u]; it; it = it -> nxt) {
int v = it -> to;
if(v == fa) continue;
dfs(v, u);
for(int i = size[u]; i >= ; i--)
for(int j = ; j <= size[v] && i + j <= k; j++)
if(i + j != )
dp[u][i + j] = min(dp[u][i + j], dp[u][i] + dp[v][j]);
size[u] += size[v];
} ans = min(ans, dp[u][k]);
} int main() {
freopen("isolate.in", "r", stdin);
freopen("isolate.out", "w", stdout); scanf("%d%d", &n, &k);
for(int i = ; i < n; i++) {
int u, v; scanf("%d%d", &u, &v);
addEdge(u, v), addEdge(v, u);
w[u]++, w[v]++;
} memset(dp, / , sizeof(dp));
ans = 0x7fffffff; dfs(, ); printf("%d", ans - k * + );
}

法二:定义dp[u][k]表示以u为根的子树中选择k个点最少需要割掉的边。同样是背包转移,如果儿子不选,dp[u][j]就要加一。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std; int n, k; const int N = ; int stot, tov[N*], nex[N*], h[N];
void add ( int u, int v ) {
tov[++stot] = v;
nex[stot] = h[u];
h[u] = stot;
} int siz[N], dp[N][N]; void dfs ( int u, int f ) {
siz[u] = ;
for ( int i = h[u]; i; i = nex[i] ) {
int v = tov[i];
if ( v == f ) continue;
dfs ( v, u );
siz[u] += siz[v];
}
dp[u][] = ;
for ( int i = h[u]; i; i = nex[i] ) {
int v = tov[i];
if ( v == f ) continue;
for ( int j = min ( k, siz[u] ); j; j -- ) {
dp[u][j] = dp[u][j] + ;
for ( int p = ; p <= min ( j, siz[v] ); p ++ ) {
dp[u][j] = min ( dp[u][j], dp[v][p] + dp[u][j-p] );
}
}
}
} int main ( ) {
freopen ( "isolate.in", "r", stdin );
freopen ( "isolate.out", "w", stdout );
scanf ( "%d%d", &n, &k );
for ( int i = ; i < n; i ++ ) {
int u, v;
scanf ( "%d%d", &u, &v );
add ( u, v );
add ( v, u );
}
memset ( dp, 0x3f3f3f3f, sizeof ( dp ) );
dfs ( , );
int ans = dp[][k];
for ( int i = ; i <= n; i ++ )
ans = min ( ans, dp[i][k] + );
printf ( "%d", ans );
return ;
}

真的难受...以前写过当时秒掉的题,今天调了两个小时打死调不出来...【注意!!】像这种求方案数的状压dp通常是需要转移不放的情况的!!少了两句话直接就爆零了...

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std; int r, c;
long long dp[][<<]; int main ( ) {
freopen ( "domino.in", "r", stdin );
freopen ( "domino.out", "w", stdout );
scanf ( "%d%d", &r, &c );
int now = ;
int l = max ( r, c ), p = min ( r, c );
r = p, c = l;
int tot = ( << r ) - ;
dp[now][tot] = ;
int pre = ( << ( r - ) );
for ( int i = ; i <= c; i ++ )
for ( int j = ; j <= r; j ++ ) {
now ^= ;
memset ( dp[now], , sizeof ( dp[now] ) );
for ( int s = ; s <= tot; s ++ ) {
int up = s & pre;
int las = s & ;
if ( !up ) {
int ss = s << | ;
dp[now][ss] += dp[now^][s];
}
if ( up && !las ) {
if ( j != ) {
int ss = ( s ^ pre ) << | ;
dp[now][ss] += dp[now^][s];
}
int ss = ( s ^ pre ) << ;
dp[now][ss] += dp[now^][s];
}
if ( up && las ) {
int ss = ( s ^ pre ) << ;
dp[now][ss] += dp[now^][s];
}
}
}
printf ( "%I64d", dp[now][tot] );
return ;
}

实际上是一道比较简单的背包了...定义dp[k][p]表示子集s的和为k时s2的值为p的状态能否到达。如果dp[j][p]为true,dp[j+c[i]][p+c[i]]和dp[j+c[i]][p]都为true。【注意】当p>j时,dp[j+c[i]][p]依然需要转移!

#include<iostream>
#include<cstdio>
using namespace std; int n, k, c[];
int dp[][]; int main ( ) {
freopen ( "coin.in", "r", stdin );
freopen ( "coin.out", "w", stdout );
scanf ( "%d%d", &n, &k );
for ( int i = ; i <= n; i ++ )
scanf ( "%d", &c[i] );
dp[][] = ;
for ( int i = ; i <= n; i ++ ) {
for ( int j = k-c[i]; j >= ; j -- )
for ( int p = k; p >= ; p -- ) {
if(p<=k-c[i])
dp[j+c[i]][p+c[i]] |= dp[j][p];
dp[j+c[i]][p] |= dp[j][p];
}
}
int ans = ;
for ( int i = ; i <= k; i ++ )
if ( dp[k][i] ) ans ++;
printf ( "%d\n", ans );
for ( int i = ; i <= k; i ++ )
if ( dp[k][i] ) printf ( "%d ", i );
return ;
}

可能是今天考了四道题的原因,做的过程中有点慌,一直死扣t2和t3导致最后没有时间看t4,t3这种类型下次一定不能再错了!!

【8.14校内测试】【DP专题】的更多相关文章

  1. 【8.30校内测试】【找规律模拟】【DP】【二分+贪心】

    对于和规律或者数学有关的题真的束手无策啊QAQ 首先发现两个性质: 1.不管中间怎么碰撞,所有蚂蚁的相对位置不会改变,即后面的蚂蚁不会超过前面的蚂蚁或者落后更后面的蚂蚁. 2.因为所有蚂蚁速度一样,不 ...

  2. 树形dp专题总结

    树形dp专题总结 大力dp的练习与晋升 原题均可以在网址上找到 技巧总结 1.换根大法 2.状态定义应只考虑考虑影响的关系 3.数据结构与dp的合理结合(T11) 4.抽直径解决求最长链的许多类问题( ...

  3. 决策单调性优化dp 专题练习

    决策单调性优化dp 专题练习 优化方法总结 一.斜率优化 对于形如 \(dp[i]=dp[j]+(i-j)*(i-j)\)类型的转移方程,维护一个上凸包或者下凸包,找到切点快速求解 技法: 1.单调队 ...

  4. 状压dp专题复习

    状压dp专题复习 (有些题过于水,我直接跳了) 技巧总结 : 1.矩阵状压上一行的选择情况 \(n * 2^n\) D [BZOJ2734][HNOI2012]集合选数 蒻得不行的我觉得这是一道比较难 ...

  5. 区间dp专题练习

    区间dp专题练习 题意 1.Equal Sum Partitions ? 这嘛东西,\(n^2\)自己写去 \[\ \] \[\ \] 2.You Are the One 感觉自己智力被吊打 \(dp ...

  6. 测试开发专题:spring-boot自定义异常返回

    上文测试开发专题:spring-boot统一异常捕获我们讨论了java异常以及如何使用Spring-Boot捕获异常,但是没有去说捕获异常后该如何进一步处理,这篇文章我们将对这个遗留的问题进行讨论. ...

  7. 【8.31校内测试】【找规律二分】【DP】【背包+spfa】

    打表出奇迹!表打出来发现了神奇的规律: 1 1 2 2 3 4 4 4 5 6 6 7 8 8 8 8 9 10 10 11 12 12 12 13 14 14 15 16 16 16 16 16.. ...

  8. 【11.8校内测试】【倒计时2天】【状压DP】【随机化?/暴力小模拟】

    Solution 数据范围疯狂暗示状压,可是一开始发现状态特别难受. 将每一层的奇偶性状压,预处理所有状态的奇偶性.每一层的输入代表的其实可以是下一层某个点可以被从这一层哪些点转移到. 所以枚举每个状 ...

  9. 【11.5校内测试】【倒计时5天】【DP】【二分+贪心check】【推式子化简+线段树】

    Solution 非常巧妙的建立DP方程. 据dalao们说题目明显暗示根号复杂度??(反正我是没看出来 因为每次分的块大小一定不超过$\sqrt n$,要不然直接每个位置开一个块答案都才为$n$. ...

随机推荐

  1. ECMAScript——(二)

    1.语法 区分大小写 变量是弱类型(定义变量时只用 var 运算符,可以将它初始化为任意值.) 每行结尾的分号可有可无(建议写上) 注释与Java一样 括号表示代码块 2.变量 变量可以不用声明,变量 ...

  2. SELinux 入门【转】

    一.前言 安全增强型 Linux(Security-Enhanced Linux)简称 SELinux,它是一个 Linux 内核模块,也是 Linux 的一个安全子系统.SELinux 主要由美国国 ...

  3. java 一个函数如何返回多个值

    在开发过程中,经常会有这种情况,就是一个函数需要返回多个值,这是一个问题!! 网上这个问题的解决方法: 1.使用map返回值:这个方法问题是,你并不知道如何返回值的key是什么,只能通过doc或者通过 ...

  4. unity 欧拉旋转

    欧拉旋转   在文章开头关于欧拉旋转的细节没有解释的太清楚,而又有不少人询问相关问题,我尽量把自己的理解写到这里,如有不对还望指出.     欧拉旋转是怎么运作的     欧拉旋转是我们最容易理解的一 ...

  5. python基础--logging模块

    很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误.警告等信息输出,python的logging模块提供了标准的日志接口,你可以通过它存储各种格式的日志,loggin ...

  6. COLLATE CHINESE_PRC_CI_AS_WS 的含义

    排序规则:COLLATE CHINESE_PRC_CI_AS_WS 的含义 在创建数据表时,常会用到这个. 含义当中,CHINESE_prc_ 是代表中国大陆.如果是台湾,则如:Chinese_TAI ...

  7. grail开发环境的搭建

    本文参考:Grails入门指南(第二版) 1. 下载jdk和Grail http://www.oracle.com/technetwork/java/javase/downloads/ http:// ...

  8. BFC 从了解到放弃

    最近工作中我突然产生了一个想法,就如我们人类面临的终极问题一般,我从哪里来?我到哪里去?在撸代码进行CSS布局的时候,我会去想,我为什么这么做?,为什么浮动的元素要用overflow?,为什么要用cl ...

  9. CF GYM100548 (相邻格子颜色不同的方案数 2014西安现场赛F题 容斥原理)

    n个格子排成一行,有m种颜色,问用恰好k种颜色进行染色,使得相邻格子颜色不同的方案数. integers n, m, k (1 ≤n, m ≤ 10^9, 1 ≤ k ≤ 10^6, k ≤ n, m ...

  10. 使用CSS3 @media 设置页面自适应

    参考CSS3 @media 查询 如果文档宽度小于 300 像素则修改背景演示(background-color): @media screen and (max-width: 300px) { bo ...