【ASC44】F - Funny Card Game
2015-07-13 13:00
260 查看
题意:给你一列牌,让你找到k个连续的子串,其中每一个子串出现次数最多的数字的出现次数为得分,问最多可以有多少分。
分析:首先可以先贪心地想一下,如果选择出来了这k个子串,那么我们总可以通过适当地对子串进行收缩,使得子串的两边既是子串的众数,那么我们就可以考虑每一个数,要么这一段只有这一个数,要么这一段的最前面一个数和这个数相同。因此我们可以用dp[i][j]来表示前i张牌分成j段且第j个人必须取第i张牌能够取得的最大的得分,dp2[i][j]为前i张牌分成j段能够取得的最大得分。再者通过一个map来记录上一次出现这个a[i]的位置,不妨设这个位置为loc。则可得转移:dp[i][j] = max(dp[i][j],dp2[i
- 1][j - 1] + 1),表示第j段只取一个数,dp[i][j] = max(dp[i][j],dp[loc][j] + 1),表示这一段两端都为a[i]的取得的最大值。对于dp2[i][j]也进行相应的维护。则可以取得答案。
代码如下:
分析:首先可以先贪心地想一下,如果选择出来了这k个子串,那么我们总可以通过适当地对子串进行收缩,使得子串的两边既是子串的众数,那么我们就可以考虑每一个数,要么这一段只有这一个数,要么这一段的最前面一个数和这个数相同。因此我们可以用dp[i][j]来表示前i张牌分成j段且第j个人必须取第i张牌能够取得的最大的得分,dp2[i][j]为前i张牌分成j段能够取得的最大得分。再者通过一个map来记录上一次出现这个a[i]的位置,不妨设这个位置为loc。则可得转移:dp[i][j] = max(dp[i][j],dp2[i
- 1][j - 1] + 1),表示第j段只取一个数,dp[i][j] = max(dp[i][j],dp[loc][j] + 1),表示这一段两端都为a[i]的取得的最大值。对于dp2[i][j]也进行相应的维护。则可以取得答案。
代码如下:
#include<bits/stdc++.h> using namespace std; const int M = 105; const int N = 100005; int dp [M],pre [M]; int dp2 [M],pre2 [M]; int a ; vector<int> vt; map<int,int> mp; int main() { freopen("funny.in","r",stdin); freopen("funny.out","w",stdout); int n,k; while(~scanf("%d%d",&n,&k)){ if(n == 0 && k == 0) break; for(int i = 1 ; i <= n ; i ++) scanf("%d",&a[i]); mp.clear(); for(int i = 1 ; i <= n ; i ++){ int loc = mp[ a[i] ]; for(int j = 1 ; j <= min(i - 1,k) ; j ++){ dp2[i][j] = dp2[i - 1][j]; pre2[i][j] = pre2[i - 1][j]; } for(int j = 1 ; j <= min(i,k) ; j ++){ dp[i][j] = pre[i][j] = 0; if(dp[i][j] < dp2[i - 1][j - 1] + 1){ dp[i][j] = dp2[i - 1][j - 1] + 1; pre[i][j] = i - 1; } if(dp2[i][j] < dp2[i - 1][j - 1] + 1){ dp2[i][j] = dp2[i - 1][j - 1] + 1; pre2[i][j] = i - 1; } if(loc && dp[i][j] < dp[loc][j] + 1){ dp[i][j] = dp[loc][j] + 1; pre[i][j] = pre[loc][j]; } if(loc && dp2[i][j] < dp[loc][j] + 1){ dp2[i][j] = dp[loc][j] + 1; pre2[i][j] = pre[loc][j]; } } mp[ a[i] ] = i; } vt.clear(); int loc = n; for(int i = k ; i >= 1 ; i --){ vt.push_back(loc); loc = pre2[loc][i]; } sort(vt.begin(),vt.end()); printf("%d\n",dp2 [k]); for(int i = 0 ; i < k - 1 ; i ++) printf("%d ",vt[i]); printf("\n"); } return 0; }
相关文章推荐
- Poco TcpServer 介绍
- [Zybo u-boot Linux系统移植]-ZYBO Zync-7000 Development Board Work Booting Linux on the ZYBO
- 冒泡排序
- 053第495题
- RHEL 6.x 搭建Rsyslog日志服务器和loganalyzer日志分析工具
- 对UITextField内容实时监听长度和内容
- Apple Mach-O Linker Warning 警告解决办法
- socket通信网络模型
- 解决一个页面多个window.onload问题
- Java Console乱码
- Leetcode算法刷题:第100题 Same Tree
- Linux环境下安装mysql
- HTTP/2笔记之连接建立
- 中国最大的融资平台
- 树状数组学习(一维)
- iOS crash 崩溃问题的追踪方法
- 闪回事务查询
- vim配置及插件安装管理
- Web安全测试解决方案
- HTTP/2笔记之开篇