HDU-4632 Palindrome subsequence

题意:给定一个字符串,长度最长为1000,问该串有多少个回文子串。

分析:设dp[i][j]表示从 i 到 j 有多少个回文子串,则有动态规划方程:

str[i] != str[j]:dp[i][j] = dp[i+1][j] + dp[i][j-1] - dp[i+1][j-1];
str[i]  = str[j]:dp[i][j] = dp[i+1][j] + dp[i][j-1] + 1.

#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;const int mod = 10007;
const int N = 1005;
char str[N];
int f[N][N];int solve(int len) {memset(f, 0, sizeof (f));for (int i = 0; i < len; ++i) {f[i][i] = 1;}for (int k = 2; k <= len; ++k) { // 枚举长度 for (int i = 0, j; i < len && (j=i+k-1) < len; ++i) {if (str[i] == str[j]) {f[i][j] = (f[i][j-1] + f[i+1][j] + 1) % mod;} else {f[i][j] = ((f[i][j-1] + f[i+1][j] - f[i+1][j-1]) % mod + mod) % mod;}}}return f[0][len-1];
}int main() {int T, ca = 0;scanf("%d", &T);while (T--) {scanf("%s", str);int len = strlen(str);printf("Case %d: %d\n", ++ca, solve(len));}return 0;
}

View Code

HDU-4638 Group

题意:给定一个序列(1-N的全排列),问任意一个区间内若将所有的数排序后,能够形成多少个不连续的子序列。

分析:对于每一个数字,记录其左边的数字和右边的数字所在的位置,然后根据相互关系维护好一个线段数量的树状数组。

#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;void getint(int &);struct Node {int No, l, r;void read(int _No) {getint(l), getint(r);No = _No;}bool operator < (const Node &t) const {return r > t.r;}
};
const int N = 100005;
int seq[N], pos[N];
int n, m;
int bit[N];
int ans[N];
Node e[N];inline int lowbit(int x) {return x & -x;
}void add(int x, int val) {for (int i = x; i <= n; i+=lowbit(i)) {bit[i] += val;}
}int sum(int x) {int ret = 0;for (int i = x; i > 0; i-=lowbit(i)) {ret += bit[i];    }return ret;
}void getint(int &t) {char ch;while ((ch = getchar()), ch < '0' || ch > '9') ;t = ch - '0';while ((ch = getchar()), ch >= '0' && ch <= '9') t = t * 10 + ch - '0';
}int main() {int T;scanf("%d", &T);while (T--) {memset(bit, 0, sizeof (bit));scanf("%d %d", &n, &m);for (int i = 1; i <= n; ++i) {getint(seq[i]);pos[seq[i]] = i;}for (int i = 1; i <= m; ++i) {e[i].read(i);}sort(e+1, e+1+m);for (int i = n; i >= 1; --i) {int cnt = 0;if (seq[i] > 1 && pos[seq[i]-1] > i) ++cnt;if (seq[i] < n && pos[seq[i]+1] > i) ++cnt;if (cnt == 0) add(i, 1);else if (cnt == 2) add(i, -1);}int last = n;for (int i = 1; i <= m; ++i) {for (int j = last; j > e[i].r; --j) {if (seq[j] > 1 && pos[seq[j]-1] < j) add(pos[seq[j]-1], 1);if (seq[j] < n && pos[seq[j]+1] < j) add(pos[seq[j]+1], 1);}last = e[i].r;ans[e[i].No] = sum(e[i].r)-sum(e[i].l-1);}for (int i = 1; i <= m; ++i) {printf("%d\n", ans[i]);}}return 0;
}

View Code

HDU-4640 Island and study-sister

题意:给定N个点,N最大为17,问从最多3个人从1号点出发到指定的K个点所花的时间最短为多少?(所花时间以到达最后一个点为准)。要求三个人的路线中不能够存在相同的点。

分析:首先通过一次dfs搜索出单个人走出某种状态所需要的最小代价,f[i][j]表示 i 状态到 j 号节点停止的最小花费。这里有一个地方要注意就是记得某个点最后到达 j 点那么也可以由上一个状态最后到达 j 点转移过来,相当于走一个点又返回到原来的位置。紧接着再通过一个dp[i]表示走出 i 状态所需的最小花费,也举是从所有停止点中取出一个最小的,最后再对dp[i]进行一些修正,将其意义变为 i 状态中若存在目标点那么这些点一定要走,而其他的点则可以由该位为空的状态递推过来取一个较小值。这样做的目的是为了后面直接枚举3^n(即将每个点分配给三个人的某一个的组合情况)来得到最终结果,否则的话如果仅仅枚举K个点的情况,那么对于剩下的点又要进行一次讨论,时间复杂度上升了。

#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;const int inf = 0x3f3f3f3f;
int n, m, K, esta;
int mp[20][20];
int f[1<<17][20]; // f[i][j]表示到达状态i,停在j的最少花费
char vis[1<<17][20];
int dp[1<<17];
int ret;int dfs(int sta, int e) {if (vis[sta][e]) return f[sta][e];vis[sta][e] = 1;for (int i = 1; i < n; ++i) {if (i == e) continue;if ((sta & (1 << i)) && mp[e][i] != inf) {f[sta][e] = min(f[sta][e], 2*mp[e][i] + dfs(sta^(1<<i), e));    }}int pre = sta ^ (1 << e);if (e != 0) {for (int i = 0; i < n; ++i) { // 起始点将由于pre的不同而不同,当pre反应只可能有0号节点来时将枚举0 if ((pre & (1 << i)) && mp[i][e] != inf) { // 说明两点之间有边相连f[sta][e] = min(f[sta][e], mp[i][e] + dfs(pre, i));}}}return f[sta][e];
}void gao(int s1, int s2, int s3, int deep) {if (deep == n) {ret = min(ret, max(dp[s1], max(dp[s2], dp[s3])));return;}gao(s1|(1<<deep), s2, s3, deep+1);gao(s1, s2|(1<<deep), s3, deep+1);gao(s1, s2, s3|(1<<deep), deep+1);
}int solve() {// 处理出一次经过若干个节点的最短距离memset(f, 0x3f, sizeof (f));memset(vis, 0, sizeof (vis));memset(dp, 0x3f, sizeof (dp));ret = inf;int LIM = 1 << n;f[1][0] = 0; // 初始化从第1个节点出发for (int i = 1; i < LIM; ++i) {for (int j = 0; j < n; ++j) {if (i & (1 << j)) dfs(i, j);    }}// 之后处理利用三次机会的组合情况for (int i = 1; i < LIM; ++i) {for (int j = 0; j < n; ++j) {dp[i] = min(dp[i], f[i][j]);}}for (int i = 1; i < LIM; ++i) {for (int j = 0; j < n; ++j) {if (i & (1 << j) && !(esta & (1<<j))) {dp[i] = min(dp[i], dp[i^(1<<j)]);}}}gao(1, 1, 1, 1);return ret == inf ? -1 : ret;
}int main() {int T, ca = 0;scanf("%d", &T);while (T--) {memset(mp, 0x3f, sizeof (mp));esta = 1; // 路线中一定包含源点 scanf("%d %d", &n, &m);int a, b, c;for (int i = 0; i < m; ++i) {scanf("%d %d %d", &a, &b, &c);--a, --b;mp[a][b] = mp[b][a] = min(mp[a][b], c);}scanf("%d", &K);for (int i = 0; i < K; ++i) {scanf("%d", &c);esta = esta | (1 << c-1);}printf("Case %d: %d\n", ++ca, solve());}return 0;
}

View Code

2013 Multi-University Training Contest 4相关推荐

  1. Sichuan University Programming Contest 2018 Preliminary

    嗯为了防止大家AK,所以这次的A题和K题我们就当做不存在好了! 经历了昨天写了两个多小时的博客没保存的心态炸裂,今天终于下了个Markdown.所以我猜这篇的格式应该会更好看一点! 好吧废话不多说 题 ...

  2. HDU 6091 - Rikka with Match | 2017 Multi-University Training Contest 5

    思路来自 某FXXL 不过复杂度咋算的.. /* HDU 6091 - Rikka with Match [ 树形DP ] | 2017 Multi-University Training Conte ...

  3. HDU 6051 - If the starlight never fade | 2017 Multi-University Training Contest 2

    /* HDU 6051 - If the starlight never fade [ 原根,欧拉函数 ] | 2017 Multi-University Training Contest 2 题意: ...

  4. HDU 6058 - Kanade's sum | 2017 Multi-University Training Contest 3

    /* HDU 6058 - Kanade's sum [ 思维,链表 ] | 2017 Multi-University Training Contest 3 题意:给出排列 a[N],求所有区间的第 ...

  5. 2017 Multi-University Training Contest - Team 3 Kanade's sum hd6058

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6058 题目: Kanade's sum Time Limit: 4000/2000 MS (J ...

  6. 2018 Multi-University Training Contest 3 Problem F. Grab The Tree 【YY+BFS】

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6324 Problem F. Grab The Tree Time Limit: 2000/1000 MS ...

  7. hdu 4925 Apple Tree--2014 Multi-University Training Contest 6

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4925 Apple Tree Time Limit: 2000/1000 MS (Java/Others ...

  8. HUST-2015 Multi-University Training Contest 9

    2015 Multi-University Training Contest 9 solutions BY xudyh 1001.Expression 记dp_{l,r}dp​l,r​​表示l,rl, ...

  9. 2018 Multi-University Training Contest 4 Problem E. Matrix from Arrays 【打表+二维前缀和】

    任意门:http://acm.hdu.edu.cn/showproblem.php?pid=6336 Problem E. Matrix from Arrays Time Limit: 4000/20 ...

  10. 2017 Multi-University Training Contest - Team 1

    2017 Multi-University Training Contest - Team 1 01     签到的 #include<bits/stdc++.h> using names ...

最新文章

  1. 又一次内存分配失败(关于overcommit_memory)
  2. 语句中如何结束本循环进入下一循环_第33 p,for遍历,循环取值最方便
  3. 计算机网络基础 — 基本术语/概念
  4. jwt思维导图,让jwt不再难懂
  5. 【Sql server: T-Sql 技术内幕 系列】之索引篇
  6. WPF-学习笔记 获取我的文档路径
  7. Netty 服务 如何 接收新的连接
  8. java se development kit可以卸载吗_首款纯电版MINI COOPER详细评测,或将国产,值得等吗?...
  9. nyoj 309 bobsledding 即河南省第四届大学生程序设计大赛第七题
  10. MAC iterm2 常用快捷键大全
  11. 〖Python〗-- 模块与包
  12. 干了四五年Android 开发了,如何突破成长中的技术瓶颈期?
  13. 老友记第一季自学笔记01
  14. wordpress采集插件自动采集伪原创免费插件
  15. 解决谷歌浏览器Chrome 代理设置不能上网的问题
  16. 如何让excel图表根据当前月份自动延伸
  17. PC发卡机器人 v1.0
  18. 档案重要吗有什么作用(转载记录避免以后麻烦)
  19. win10 远程桌面和向日葵远控哪个好用?
  20. Bootstrap 表格内容水平、垂直居中

热门文章

  1. 【mysql】在Linux中通过yum安装MySQL数据库,可以实现远程登录数据库
  2. 分享:MySQL 学习笔记(三)
  3. perfdog 性能狗之Jank
  4. Windows 网络无法ping通的解决方法
  5. c语言经典游戏,C语言——经典小游戏——打砖块
  6. Web前端初学者,需用了解的7大HTML知识点
  7. 解密初、中、高级程序员的进化之路(前端)
  8. delphi语言转为汇编语言_计算机语言
  9. 网站二次开发如何防止别人打包源码_企业网站制作前需注意的几个事项
  10. java quartz 教程_Quartz视频教程