首页 > 无题6

无题6

题解:

第一题:类比只有三根,四根的柱子的汉诺塔,柱子越多越好,柱子盘子固定,步数一定,如果我有K个盘子,J个柱子,把P个盘子移到1个柱子的步数为F【P】【J】, 那么剩余K-P个盘子移到1个柱子就是F【K-P】【J-1】, 放P的柱子不能再放了,然后我们又有J个可以自由移动的柱子,

所以f[ i ][ j ] = min(f[ k ][ j ] * 2 + f[ i - k ][ j -1 ]), 枚举k即可;

 

#include
using namespace std;
long long dp[70][70];int main(){freopen("hanoi.in","r",stdin);freopen("hanoi.out","w",stdout);int n, m;scanf("%d%d", &n, &m);memset(dp, 0x3f, sizeof(dp));dp[1][3] = 1;for(int i = 2; i <= n; i++) dp[i][3] = ((dp[i - 1][3] + 1) << 1) - 1;for(int i = 1; i <= 65; i++) dp[0][i] = 0, dp[1][i] = 1, dp[2][i] = 3;for(int i = 4; i <= m; i++)for(int j = 3; j <= n; j++){for(int k = 1; k <= j; k++)dp[j][i] = min(2 * dp[j - k][i] + dp[k][i - 1], dp[j][i]);}printf("%lld
", dp[n][m]);
}          
View Code

 

 

 

第二题:

我只想说cyj太聪明了

#include
using namespace std;
const int M = 200005;
char s[M]; int b[M];
struct node{int val, id;bool operator < (const node &rhs) const{return val < rhs.val;}
}a[M];int q[M], h, t;
int main(){freopen("rank.in","r",stdin);freopen("rank.out","w",stdout);int n, fg = 0;scanf("%d", &n);char now = 'a';for(int i = 1; i <= n; i++){scanf("%d", &a[i].val), a[i].id = i; b[i] = a[i].val;}sort(a + 1, a + 1 + n);int lst = 0; a[n+1].id = -1;for(int i = 1; i <= n; i++){node p; p.val = i;int pos = lower_bound(a + 1, a + 1 + n, p) - a;if(b[a[pos].id + 1] > lst) s[a[pos].id] = now;else s[a[pos].id] = ++now;lst = b[a[pos].id + 1];if(now > 'z'){fg = -1;break;}}if(fg)puts("-1");else for(int i = 1; i <= n; i++)printf("%c", s[i]);
} 
View Code

 

第三题:期望DP,以前讲过, 终于还是写了这道题

F化简:f(u) = sum ( f(v) ) + deg(u) ,  v is u's child

G化简:g(u) = g(fa(u)) + f(fa(u)) - f(u);

注意求完f,然后用f更新g, 修改f[ 1 ] = 0,  因为1不会再往上走,但更新g之前不能改F1,是有实际有意的;

#include
using namespace std;
#define ex(i, u) for(int i = h[u]; i; i = G[i].nxt)
const int mod = 1e9 + 7, M = 1e5 + 5;
int P = 20, f[M], g[M], F[M], GV[M], dep[M], deg[M], anc[M][25], h[M], tot;
struct edge{ int nxt, v;}G[M<<1];
void add(int u, int v){G[++tot].v = v, G[tot].nxt = h[u], h[u] = tot;}
inline int moc(int a){ return a >= mod ? a - mod : a;}
void dfs1(int u, int fa){anc[u][0] = fa;for(int p = 1; p <= P; p++)anc[u][p] = anc[anc[u][p - 1]][p - 1];ex(i, u){int v = G[i].v;if(v == fa)continue;dfs1(v, u);f[u] = moc(f[u] + f[v]);}f[u] = moc(f[u] + deg[u]);
}void dfs2(int u, int fa){dep[u] = dep[fa] + 1;    F[u] = moc(F[fa] + f[u]);GV[u] = moc(GV[fa] + g[u]);ex(i, u){int v = G[i].v;if(v == fa)continue;g[v] = (g[u] + f[u] - f[v] + mod) % mod;dfs2(v, u);}
}int get(int u, int v){if(dep[u] < dep[v])swap(u, v);int t = dep[u] - dep[v];for(int p = 0; t; t >>= 1, p++)if(t & 1) u = anc[u][p];if(u == v) return u;for(int p = P; p >= 0; p--)if(anc[u][p] != anc[v][p])u = anc[u][p], v = anc[v][p];return anc[u][0];
}int main(){freopen("tree.in","r",stdin);freopen("tree.out","w",stdout);int n, q, u, v;scanf("%d%d", &n, &q);for(int i = 1; i < n; i++){scanf("%d%d", &u, &v);add(u, v); add(v, u);deg[u]++; deg[v]++;}dfs1(1, 0);F[0] = -f[1];dfs2(1, 0);//for(int i = 1; i <= n; i++)printf("%d %d %d %d %d
", i, f[i], g[i], F[i], GV[i]);f[1] = 0;while(q--){scanf("%d%d", &u, &v);int lca = get(u, v), flca = anc[lca][0];int ans = ( (F[u] - F[lca] + GV[v] - GV[lca]) % mod + mod ) % mod;printf("%d
", ans);}
}
View Code

 

转载于:https://www.cnblogs.com/EdSheeran/p/9690767.html

更多相关:

  •         Apache POI是一个开源的利用Java读写Excel,WORD等微软OLE2组件文档的项目。        我的需求是对Excel的数据进行导入或将数据以Excel的形式导出。先上简单的测试代码:package com.xing.studyTest.poi;import java.io.FileInputSt...

  • 要取得[a,b)的随机整数,使用(rand() % (b-a))+ a; 要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a; 要取得(a,b]的随机整数,使用(rand() % (b-a))+ a + 1; 通用公式:a + rand() % n;其中的a是起始值,n是整数的范围。 要取得a到b之间的...

  • 利用本征图像分解(Intrinsic Image Decomposition)算法,将图像分解为shading(illumination) image 和 reflectance(albedo) image,计算图像的reflectance image。 Reflectance Image 是指在变化的光照条件下能够维持不变的图像部分...

  • 题目:面试题39. 数组中出现次数超过一半的数字 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 示例 1: 输入: [1, 2, 3, 2, 2, 2, 5, 4, 2] 输出: 2 限制: 1 <= 数组长度 <= 50000 解题: cl...

  • 题目:二叉搜索树的后序遍历序列 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。 参考以下这颗二叉搜索树:      5     /    2   6   /  1   3示例 1: 输入: [1,6,3,2,5] 输出...

  • 用python编写乘法口诀表的方法 发布时间:2020-08-25 11:46:35 来源:亿速云 阅读:60 作者:小新 用python编写乘法口诀表的方法?这个问题可能是我们日常学习或工作经常见到的。希望通过这个问题能让你收获颇深。下面是小编给大家带来的参考内容,让我们一起来看看吧! 第一种:使用for遍历循环嵌套for x in...

  • //很长一段时间我都只使用以下方式做数组循环,具体原因看数据 var aa = for (var i = 0, l = aa.length; i < l; i++) { var a = aa[i];} 数据采集图片来源于网友 很明显,for循环第二种方式完胜!!! 至于for in、forEach什么的,不知道甩他们多少...

  • 目录 1. Scene Graph Generation with External Knowledge and Image Reconstruction 2. Knowledge Acquisition for Visual Question Answering via Iterative Querying Author...

  • 基础题1: 输入一个正整数 n (1≤n≤10)和n 阶方阵a的元素,如果方阵a中的所有元素都沿主对角线对称,输出“Yes”, 否则,输出“No”。主对角线为从矩阵的左上角至右下角的连线,方阵a中的所有元素都沿主对角线对称指对所有i, k,a[i][k]和a[k][i]相等。输入输出示例如下: 输入: 3 1 2 3 4 5 6 7...

  • 程序流程控制 分支 顺序 循环 if switch&case 1 2 3 调整 break 1.6 前 switch(byte、short、char、int) 1.7 可放String 循环 while(次数不确定) do while for(确定次数) break(跳出本层循环) continue(跳出本次循环)     *   2...

  • 题目:正则表达式匹配 请实现一个函数用来匹配包含'. '和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但与"aa.a"和"ab*a"均不匹配。 示例 1:...

  • 题意:就是在n*m的格子中放“炮”(中国象棋中的棋子)问有多少种放法,使得没有任意的两个炮相互攻击 思路:我们很容易的得到一列或者一行中最多放下两个炮(我也只能得到这些了,满脑子状压,但数据范围有100),这篇博客些的很好(传送门),我们定义dp[i][j][k]代表前i行我们有j列式有2个棋子,有k列是一个棋子,那么我们空的列的个数...

  • 虽然也是一道dp的入门题,但就是想不到,或者说不会实现。dp还是要多做题。 链接:https://www.luogu.org/problemnew/show/P1164   我们可以设dp[i][j]表示以考虑完第i件,恰好消费j元的方案数。那么dp[i][j]=dp[i-1][j]+dp[i-1][j-a[i]],也就是讨论第i件点...

  • bzoj1260,懒得复制,戳我戳我 Solution: 这种题目我不会做qwq,太菜了区间打牌(dp) 用f[l][r]表示从l到r最少需要染几次色。状态转移方程: 1.(f[l][r]=min(f[l][i],f[i+1][r]) (l<=i

  • 题目背景 博弈正在机房颓一个叫做《模拟城市2.0》的游戏。 2048年,经过不懈努力,博弈终于被组织委以重任,成为D市市委书记!他勤学好问,励精图治,很快把D市建设成富强民主文明和谐的美好城市。为了进一步深化发展,他决定在海边建立一个经济开发区。 题目描述 已知开发区的建筑地块是一个n×nn imes nn×n的矩形,而开发...