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 = ;
const int N = ;
char str[N];
int f[N][N]; int solve(int len) {
memset(f, , sizeof (f));
for (int i = ; i < len; ++i) {
f[i][i] = ;
}
for (int k = ; k <= len; ++k) { // 枚举长度
for (int i = , j; i < len && (j=i+k-) < len; ++i) {
if (str[i] == str[j]) {
f[i][j] = (f[i][j-] + f[i+][j] + ) % mod;
} else {
f[i][j] = ((f[i][j-] + f[i+][j] - f[i+][j-]) % mod + mod) % mod;
}
}
}
return f[][len-];
} int main() {
int T, ca = ;
scanf("%d", &T);
while (T--) {
scanf("%s", str);
int len = strlen(str);
printf("Case %d: %d\n", ++ca, solve(len));
}
return ;
}

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 = ;
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 = ;
for (int i = x; i > ; i-=lowbit(i)) {
ret += bit[i];
}
return ret;
} void getint(int &t) {
char ch;
while ((ch = getchar()), ch < '' || ch > '') ;
t = ch - '';
while ((ch = getchar()), ch >= '' && ch <= '') t = t * + ch - '';
} int main() {
int T;
scanf("%d", &T);
while (T--) {
memset(bit, , sizeof (bit));
scanf("%d %d", &n, &m);
for (int i = ; i <= n; ++i) {
getint(seq[i]);
pos[seq[i]] = i;
}
for (int i = ; i <= m; ++i) {
e[i].read(i);
}
sort(e+, e++m);
for (int i = n; i >= ; --i) {
int cnt = ;
if (seq[i] > && pos[seq[i]-] > i) ++cnt;
if (seq[i] < n && pos[seq[i]+] > i) ++cnt;
if (cnt == ) add(i, );
else if (cnt == ) add(i, -);
}
int last = n;
for (int i = ; i <= m; ++i) {
for (int j = last; j > e[i].r; --j) {
if (seq[j] > && pos[seq[j]-] < j) add(pos[seq[j]-], );
if (seq[j] < n && pos[seq[j]+] < j) add(pos[seq[j]+], );
}
last = e[i].r;
ans[e[i].No] = sum(e[i].r)-sum(e[i].l-);
}
for (int i = ; i <= m; ++i) {
printf("%d\n", ans[i]);
}
}
return ;
}

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

2013 Multi-University Training Contest 4的更多相关文章

  1. Integer Partition(hdu4658)2013 Multi-University Training Contest 6 整数拆分二

    Integer Partition Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...

  2. Partition(hdu4651)2013 Multi-University Training Contest 5

    Partition Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  3. ACM ICPC Central Europe Regional Contest 2013 Jagiellonian University Kraków

    ACM ICPC Central Europe Regional Contest 2013 Jagiellonian University Kraków Problem A: Rubik’s Rect ...

  4. Partition(hdu4651)2013 Multi-University Training Contest 5----(整数拆分一)

    Partition Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  5. JSU 2013 Summer Individual Ranking Contest - 5

    JSU 2013 Summer Individual Ranking Contest - 5 密码:本套题选题权归JSU所有,需要密码请联系(http://blog.csdn.net/yew1eb). ...

  6. HDU4888 Redraw Beautiful Drawings(2014 Multi-University Training Contest 3)

    Redraw Beautiful Drawings Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. HDU 2018 Multi-University Training Contest 3 Problem A. Ascending Rating 【单调队列优化】

    任意门:http://acm.hdu.edu.cn/showproblem.php?pid=6319 Problem A. Ascending Rating Time Limit: 10000/500 ...

  8. 2015 Multi-University Training Contest 8 hdu 5390 tree

    tree Time Limit: 8000ms Memory Limit: 262144KB This problem will be judged on HDU. Original ID: 5390 ...

  9. hdu 4946 2014 Multi-University Training Contest 8

    Area of Mushroom Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  10. 2016 Multi-University Training Contest 2 D. Differencia

    Differencia Time Limit: 10000/10000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tot ...

随机推荐

  1. 定义提示符 PS1 PS4

    PS1,如:[xiluhua@vm-xiluhua][~]$ # prompt PS1 export PATH BLUE=$(tput setaf ) PURPLE=$(tput setaf ) YE ...

  2. php number_format()保留小数点后几位

    [PHP_保留两位小数的相关函数] php保留两位小数并且四舍五入 Php代码   1     $num = 123213.666666;  2     echo sprintf("%.2f ...

  3. Oracle性能优化--DBMS_PROFILER

      想看到过程或者函数执行每一步的过程:想看到每一步所占的时间吗?借助profiler吧:它可以满足你来分析过程/函数执行比较久:可以直接快速找到病因:从而可以优化那一步需要优化下.        一 ...

  4. pgadmin(IDE)工具连接postgres数据库

    1. 下载软件        软件地址:http://www.pgadmin.org/download/pgagent.php   2.安装软件    安装过程:略    打开软件64位会出现  “无 ...

  5. day3 python 函数

    常犯的错误: IndentationError:expected an indented block说明此处需要缩进,你只要在出现错误的那一行,按空格或Tab(但不能混用)键缩进就行... 函数是指一 ...

  6. 修改sql2005字段

    alter table 表名 add 字段名 数据类型 default 默认值 增加:alter table AdCategory ADD SEOTitleNo varchar(50); 删除:ALT ...

  7. mybatis+springMVC新感悟

    一直以为按照例子里写的.先编写User实体类,之后在编写User.xml之后在配置文件里指明接口文件.然后在controller中就可以通过就可以通过定义接口,在取值 IUserOperation u ...

  8. sscanf 函数 分类: POJ 2015-08-04 09:19 4人阅读 评论(0) 收藏

    sscanf 其实很强大 分类: 纯C技术 技术笔记 2010-03-05 16:00 12133人阅读 评论(4) 收藏 举报 正则表达式stringbuffercurlgoogle 最近在做日志分 ...

  9. c++map的用法 分类: POJ 2015-06-19 18:36 11人阅读 评论(0) 收藏

    c++map的用法 分类: 资料 2012-11-14 21:26 10573人阅读 评论(0) 收藏 举报 最全的c++map的用法 此文是复制来的0.0 1. map最基本的构造函数: map&l ...

  10. C#代码开发规范

    Wrod下载           C#代码开发规范     文件状态: [√] 草稿 [  ] 正式 [  ] 修改 文件标识: 当前版本: 1.1 作    者: Empty 联系电话: 最后更新: ...