划分型DP
来源:互联网 发布:波士顿矩阵问题类例子 编辑:程序博客网 时间:2024/05/16 17:25
1.乘积最大(NOIP2000)
http://codevs.cn/problem/1017/
方程:
f[i][j] = max{f[k][j-1] + to_num(k+1~i)} (1 <= k < i)
to_num(low~high)表示将第low位到第high位转化成一个数字
代码:
#include<bits/stdc++.h>#define MAXN 50#define MAXK 10using namespace std;int n, k;char str[MAXN];long long f[MAXN][MAXK];long long to_num(int low, int high){ long long ret = 0; for (int i = low; i <= high; i++) ret = ret * 10 + (str[i - 1] - '0'); return ret;}int main(){ scanf("%d%d", &n, &k); scanf("%s", str); memset(f, 0, sizeof(f)); for (int i = 1; i <= n; i++) f[i][0] = to_num(1, i); for (int j = 1; j <= k; j++) for (int i = 1; i <= n; i++) for (int l = j; l < i; l++) f[i][j] = max(f[i][j], f[l][j - 1] * to_num(l + 1, i)); printf("%d\n", f[n][k]); return 0;}
2.数的划分(NOIP2001提高组)
http://codevs.cn/problem/1039/
方程:
f[i][j] = f[i - j][j] + f[i - 1][j - 1] (1 <= j <= min{i, k})
代码:
#include<bits/stdc++.h>#define MAXN 300#define MAXK 10using namespace std;int n, k;int f[MAXN][MAXK];int main(){ scanf("%d%d", &n, &k); memset(f, 0, sizeof(f)); f[0][0] = 1; for (int i = 1; i <= n; i++) for (int j = 1; j <= min(i, k); j++) f[i][j] = f[i - j][j] + f[i - 1][j - 1]; printf("%d", f[n][k]); return 0;}
3.统计单词个数(NOIP2001提高组)
http://codevs.cn/problem/1040/
方程:
f[i][k]=max(f[i][k], f[j][k-1]+word_cnt(j+1~i))
f[i][k]表示把前i个字母分成k个部分的最优解
word_cnt(low~high)表示从low到high位置的最多的单词数
PS:预处理很麻烦。
代码:
#include<bits/stdc++.h>#define MAX_LEN 300#define MAX_K 50#define MAX_S 10using namespace std;int n, p, k, s;char str[MAX_LEN];//字母串 char word[MAX_S][MAX_LEN];//字典 char temp[MAX_LEN];//临时字符串 int word_len[MAX_S];//word_len[i]-word[i]的长度 int strt[MAX_LEN];//temp[i]-以str[i]开头的单词长度 int word_cnt[MAX_LEN][MAX_LEN];//word_cnt[i][j]-str[i]~str[j]之间最多的单词数int f[MAX_LEN][MAX_K];//f[i][j]-到str[i]为止分成j份最多的单词数void get_substr(int start, int length){ for (int i = 0; i < MAX_LEN; i++) temp[i] = '\0'; for (int i = 0; i < length; i++) temp[i] = str[start + i];}void work(){ scanf("%d%d", &p, &k); for (int i = 0; i < p; i++) scanf("%s", &str[1 + i * 20]); p *= 20; scanf("%d", &s); for (int i = 0; i < s; i++) { scanf("%s", word[i]); word_len[i] = strlen(word[i]); } memset(strt, 0, sizeof(strt)); for (int i = 1; i <= p; i++) for (int j = 0; j < s; j++) { get_substr(i, word_len[j]); if ((strcmp(word[j], temp) == 0) && ((strt[i] == 0) || (strt[i] > word_len[j]))) strt[i] = word_len[j]; } memset(word_cnt, 0, sizeof(word_cnt)); for (int i = 1; i <= p; i++) for (int j = i; j <= p; j++) { word_cnt[i][j] = word_cnt[i][j - 1]; for (int l = i; l <= j; l++) if (strt[l] == j - l + 1) word_cnt[i][j] += 1; } memset(f, 0, sizeof(f)); for (int j = 1; j <= k; j++) for (int i = j; i <= p; i++) for (int l = j - 1; l < i; l++) f[i][j] = max(f[i][j], f[l][j - 1] + word_cnt[l + 1][i]); printf("%d\n", f[p][k]);}int main(){ scanf("%d", &n); for (int i = 0; i < n; i++) work(); return 0;}
0 0
- 【划分型DP】整数划分
- 划分型DP
- 划分型循环DP
- 划分型DP相关
- 划分型dp
- 【划分型DP】数的划分
- 【划分型DP】乘积最大
- 【划分型DP】数字游戏
- wikioi1039数的划分(划分型dp)
- CODEVS 1039 数的划分(划分型DP)
- [poj 1191] 棋盘分割 划分型DP
- 【划分型DP】统计单词个数
- <划分型DP>【noip 2000】乘积最大
- 集合划分 DP
- 划分数(DP)
- 划分数问题 DP
- 划分问题(dp)
- 区间DP 整数划分
- centos6更新python2.7
- github发布一个稳定版本packagist的composer包
- 微信小程序wx.request请求用POST后台得不到传递数据
- jRegistry.dll在两个项目中同时使用无法加载
- activiti工作流的web流程设计器整合视频教程 SSM和独立部署
- 划分型DP
- ajax中的POST和GET传值
- 十进制数转换成二进制数
- xpages从Excel中导入数据
- C++——三分答案模板——UmBasketella
- 后台获取Form中的值
- get_browser()用法
- 实现Android后台发邮件
- C++ 深拷贝与浅拷贝