题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1702

题目大意:给定有很多数字组成的诗,譬如 “AABB”, “ABAB”, “ABBA” and “AAAA”形式的诗句是押韵的。从中挑选,求最多可以构成多少押韵句,并且输出这些句子在原序列中的位置。

Sample Input

15
1 2 3 1 2 1 2 3 3 2 1 1 3 2 23
1 2 3

Sample Output

3
1 2 4 5
7 8 9 10
11 12 14 150

分析:设dp[i]表示从 1 到 i 之间押韵句的最大数目,f(i,j)表示当[i,j]之间可以组出一句押韵句时为1,否则为0

    则dp[i] = max{dp[i-1] , dp[j] + f(j+1,i)}

    当(i,j)之间有2个数出现的次数大于等于2时,f(i,j)=1,这2个数可以相等,即1个数出现4次

    路径打印课真是乱啊

代码如下:

  

 1 # include<iostream>
 2 # include<cstdio>
 3 # include<vector>
 4 # include<algorithm>
 5 using namespace std;
 6 const int N = 4005;
 7 int data[N],ks[N];
 8 int n,kn;
 9 int dp[N];
10 vector<int> path[N];    //记录路径
11 vector<int> pos[N];
12 int par[N];     //路径压缩
13 int out[N/4];   //输出路径
14
15 void solve()
16 {
17     if(n < 4)
18     {
19         printf("0\n\n");
20         return ;
21     }
22     kn = n;
23     sort(ks,ks+kn);     //原序列复制后排序
24     kn = unique(ks,ks+kn) - ks;     //去重函数,返回相邻不重复的个数,即元素种类数
25     int i,j,k;
26     for(i=0; i<n; i++)
27     {
28         data[i] = lower_bound(ks,ks+kn,data[i]) - ks;
29         //lower_bound()返回一个 iterator 它指向在[first,last)标记的有序序列中可以插入value,而不会破坏容器顺序的第一个位置,而这个位置标记了一个大于等于value 的值。
30     }
31     for(i=0; i<=3; i++)
32     {
33         dp[i] = 0;
34         par[i] = -1;
35     }
36     vector<int >tmp;
37     for(i=3; i<n; i++)
38     {
39         dp[i+1] = dp[i];
40         path[i+1] = path[i];
41         par[i+1] = par[i];
42         for(j=0; j<kn; j++)
43             pos[j].clear();
44         tmp.clear();
45         for(j=i; j>=0; j--)
46         {
47             k = data[j];
48             pos[k].push_back(j+1);
49             if(pos[k].size()==2)
50             {
51                 tmp.push_back(pos[k][0]);
52                 tmp.push_back(pos[k][1]);
53                 pos[k].clear();
54                 if(tmp.size()==4) break;
55             }
56         }
57         if(j >= 0)
58         {
59             if(dp[i+1] < dp[j]+1)
60             {
61                 dp[i+1] = dp[j] + 1;
62                 sort(tmp.begin(),tmp.end());
63                 path[i+1] = tmp;    //同为vector类型,可赋值
64                 par[i+1] = j;
65             }
66         }
67     }
68     printf("%d\n",dp[n]);
69     int u;
70     u =n;
71     for(i=dp[n]-1; i>=0; i--)
72     {
73         out[i] = u;
74         u= par[u];
75     }
76     for(i=0; i<dp[n]; i++)
77     {
78         for(j=0; j<3; j++)
79         {
80             printf("%d ",path[out[i]][j]);
81         }
82         printf("%d\n",path[out[i]][j]);
83     }
84     puts("");
85 }
86
87 int main()
88 {
89     while(scanf("%d",&n)!=EOF)
90     {
91         for(int i =0; i<n; i++)
92         {
93             scanf("%d",&data[i]);
94             ks[i] = data[i];
95         }
96         solve();
97     }
98     return 0;
99 }

转载于:https://www.cnblogs.com/acm-bingzi/p/3330319.html

ZOJ 2702 Unrhymable Rhymes(DP)相关推荐

  1. ZOJ 1013 Great Equipment(DP)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1013 采用动态规划解决. 设f[n][x][y] 表示前n辆车装 ...

  2. 求三角形最大面积(DP)

    求三角形最大面积(DP) 在OJ上奇迹般WA了:WA:70. Why? #include <iostream> #include <string.h> using namesp ...

  3. LeetCode 编辑距离 II(DP)

    1. 题目 给你两个单词 s 和 t,请你计算出将 s 转换成 t 所使用的最少操作数. 你可以对一个单词进行如下两种操作: 删除一个字符 替换一个字符 注意: 不允许插入操作 题目保证有解 示例: ...

  4. LeetCode 1220. 统计元音字母序列的数目(DP)

    文章目录 1. 题目 2. 解题 1. 题目 给你一个整数 n,请你帮忙统计一下我们可以按下述规则形成多少个长度为 n 的字符串: - 字符串中的每个字符都应当是小写元音字母('a', 'e', 'i ...

  5. LeetCode 265. 粉刷房子 II(DP)

    文章目录 1. 题目 2. 解题 1. 题目 假如有一排房子,共 n 个,每个房子可以被粉刷成 k 种颜色中的一种,你需要粉刷所有的房子并且使其相邻的两个房子颜色不能相同. 当然,因为市场上不同颜色油 ...

  6. LeetCode 256. 粉刷房子(DP)

    文章目录 1. 题目 2. 解题 1. 题目 假如有一排房子,共 n 个,每个房子可以被粉刷成红色.蓝色或者绿色这三种颜色中的一种,你需要粉刷所有的房子并且使其与相邻的两个房子颜色不能相同. 当然,因 ...

  7. LeetCode 1223. 掷骰子模拟(DP)

    1. 题目 有一个骰子模拟器会每次投掷的时候生成一个 1 到 6 的随机数. 不过我们在使用它时有个约束,就是使得投掷骰子时,连续 掷出数字 i 的次数不能超过 rollMax[i](i 从 1 开始 ...

  8. LeetCode 1155. 掷骰子的N种方法(DP)

    1. 题目 这里有 d 个一样的骰子,每个骰子上都有 f 个面,分别标号为 1, 2, -, f. 我们约定:掷骰子的得到总点数为各骰子面朝上的数字的总和. 如果需要掷出的总点数为 target,请你 ...

  9. LeetCode 1139. 最大的以 1 为边界的正方形(DP)

    1. 题目 给你一个由若干 0 和 1 组成的二维网格 grid,请你找出边界全部由 1 组成的最大 正方形 子网格,并返回该子网格中的元素数量.如果不存在,则返回 0. 示例 1: 输入:grid ...

最新文章

  1. 大写的服,看完这篇你还不懂RocketMQ算我输
  2. “人工智能大脑”跳槽记:吴恩达所理解的智能
  3. jQuery Event.stopPropagation() 函数详解
  4. mysql 排名_微服务架构下,如何利用Mysql的limit配合orderby进行排名统计
  5. excel取整函数_数据分析小白学习之路(三)——Excel多练熟能生巧
  6. MySQL索引和SQL调优手册
  7. 使用Chatkit构建Node.js命令行聊天应用程序
  8. 虚幻4渲染系统结构解析
  9. php friso,php binding 不兼容php7
  10. 解决mysql地区时间错误_mysql time zone时区的错误解决
  11. ReactNative入门 —— 动画篇(下)
  12. Windows安装nginx服务
  13. fastreport java 集成_报表生成器配置FastReport.Net环境
  14. Android Media Framework(3): Stagefright框架流程解读
  15. Git官网下载文件提示无法访问此网站的解决办法
  16. 吃妖怪的萝莉和帅气道长大叔,古风治愈漫画温暖来袭!
  17. 漏洞库:爬取CNVD-国家信息安全漏洞共享平台漏洞库
  18. 戴尔游匣G15怎么样?真实体验不翻车
  19. 光网视与您相约安防工程高级管理人员培训--江苏站
  20. Postman的API授权、Cookies和证书

热门文章

  1. mybatis resultMap 的日期字段无法获取时分秒的两个问题
  2. 树莓派 QT 编程下的硬件中断
  3. 【算法】Dijkstra算法(单源最短路径问题) 邻接矩阵和邻接表实现
  4. liunx内核中的互斥自旋锁和读写自旋锁的实现详解
  5. Pixhawk原生固件PX4之串口添加读取传感器实现
  6. Codeforces Round #506 (Div. 3) - C. Maximal Intersection (思维,模拟)
  7. 拆分字符串使唯一子字符串的数目最大
  8. 【Linux】虚拟地址空间
  9. linux /proc/net/arp
  10. 服务器开发中网络数据分析与故障排查经验