南昌邀请赛网络赛 D.Match Stick Game

题目传送门

题目就会给你一个长度为n的字符串,其中\(1<n<100\)。这个字符串是一个表达式,只有加减运算符,然后输入的每一个字符都是可以由若干个火柴棒拼接而成的。

现在在不改变每个数的位数,数的总数以及运算符的个数的前提下,可以对火柴棒重新拼接。询问最后可以拼接出来的最大值是多少。

这个自己看下题目可能要清楚一些= =

 

每一个字符都是由若干个火柴棒构成的,我们可以考虑类似于背包的思路来求解。

因为每个数的位数最后都没发生变化,所以我们可以预处理出\(f[i][j]\)以及\(g[i][j]\),分别表示\(i\)位数由\(j\)根火柴构成的最大/最小值。

因为这里除开火柴棒个数之外还涉及到了加减号,所以我们定义\(dp(i,j,0/1)\)为前\(i\)个数字,用了\(j\)根火柴棒,并且当前这个数字前面是\(-\)还是\(+\)。

由于数据范围比较小,所以考虑加和减两种情况进行合理转移就行了。

详见代码:

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int N = 1005;
  5. int n, T;
  6. char s[N] ;
  7. int len[N] ;
  8. ll dp[105][N][2], f[105][N], g[105][N];
  9. int trans1[10] = {0, 0, 1, 7, 4, 5, 9, 8} ;
  10. int trans2[10] = {0, 0, 1, 7, 4, 2, 0, 8} ;
  11. int num ;
  12. int main() {
  13. cin >> T;
  14. for(int i = 1; i <= 10; i++)
  15. for(int j = 2; j < N; j++) {
  16. g[i][j] = 1e14;
  17. f[i][j] = f[i][j - 1] ;
  18. for(int k = 2; k <= 7; k++) {
  19. if(j - k >= 0) f[i][j] = max(f[i - 1][j - k] * 10 + trans1[k], f[i][j]) ;
  20. }
  21. }
  22. for(int i = 1; i <= 10; i++)
  23. for(int j = 2; j < N; j++) {
  24. if(i == 1) {
  25. g[i][j] = 1;
  26. continue ;
  27. }
  28. g[i][j] = g[i][j - 1] ;
  29. for(int k = 2; k <= 7; k++) {
  30. if(j - k >= 0) g[i][j] = min(1ll * g[i - 1][j - k] * 10 + 1ll * trans2[k], g[i][j]) ;
  31. }
  32. }
  33. while(T--) {
  34. memset(dp, 0, sizeof(dp)) ;
  35. scanf("%d", &n);
  36. scanf("%s", s + 1);
  37. int cnt = 0, x = 0, num = 0;
  38. for(int i = 1; i <= n; i++) {
  39. if(s[i] == '+' || s[i] == '-') {
  40. len[++num] = cnt ;
  41. cnt = 0;
  42. if(s[i] == '+') x += 2;
  43. else x += 1;
  44. } else {
  45. cnt++;
  46. if(s[i] == '1') x += 2 ;
  47. else if(s[i] == '7') x += 3 ;
  48. else if(s[i] == '4') x += 4 ;
  49. else if(s[i] == '5' || s[i] == '2' || s[i] == '3') x += 5;
  50. else if(s[i] == '0' || s[i] == '6' || s[i] == '9') x += 6;
  51. else x += 7;
  52. }
  53. }
  54. len[++num] = cnt;
  55. for(int i = 2; i <= x; i++) dp[1][i][0] = dp[1][i][1] = f[len[1]][i] ;
  56. for(int i = 2; i <= num; i++) {
  57. for(int j = 2; j <= x; j++) {
  58. for(int k = 2; k <= j; k++) {
  59. if(j - k - 2 >= 2) {
  60. dp[i][j][1] = max(dp[i][j][1], dp[i - 1][j - k - 2][1] + f[len[i]][k]) ;
  61. dp[i][j][1] = max(dp[i][j][1], dp[i - 1][j - k - 2][0] + f[len[i]][k]) ;
  62. }
  63. if(j - k - 1 >= 2) {
  64. dp[i][j][0] = max(dp[i][j][0], dp[i - 1][j - k - 1][0] - g[len[i]][k]) ;
  65. dp[i][j][0] = max(dp[i][j][0], dp[i - 1][j - k - 1][1] - g[len[i]][k]) ;
  66. }
  67. }
  68. }
  69. }
  70. ll ans = 0;
  71. ans = max(ans, max(dp[num][x][0], dp[num][x][1])) ;
  72. cout << ans << '\n';
  73. }
  74. return 0 ;
  75. }

南昌邀请赛网络赛 D.Match Stick Game(dp)的更多相关文章

  1. 2019 ICPC南昌邀请赛网络赛比赛过程及题解

    解题过程 中午吃饭比较晚,到机房lfw开始发各队的账号密码,byf开始读D题,shl电脑卡的要死,启动中...然后听到谁说A题过了好多,然后shl让blf读A题,A题blf一下就A了.然后lfw读完M ...

  2. POJ-2796 & 2019南昌邀请赛网络赛 I. 区间最大min*sum

    http://poj.org/problem?id=2796 https://nanti.jisuanke.com/t/38228 背景 给定一个序列,对于任意区间,min表示区间中最小的数,sum表 ...

  3. [2019南昌邀请赛网络赛D][dp]

    https://nanti.jisuanke.com/t/38223 Xiao Ming recently indulges in match stick game and he thinks he ...

  4. icpc 南昌邀请赛网络赛 Max answer

    就是求区间和与区间最小值的积的最大值 但是a[i]可能是负的 这就很坑 赛后看了好多dalao的博客 终于a了 这个问题我感觉可以分为两个步骤 第一步是对于每个元素 以它为最小值的最大区间是什么 第二 ...

  5. icpc 南昌邀请赛网络赛 Subsequence

    题目链接:https://nanti.jisuanke.com/t/38232 就是判断输入是不是子序列 没想到贡献了将近十几次罚时..........可以说是菜的真实了 用cin cout超时了 改 ...

  6. 2019 ICPC南昌邀请赛 网络赛 K. MORE XOR

    说明 \(\oplus x​\)为累异或 $ x^{\oplus(a)}​$为异或幂 题意&解法 题库链接 $ f(l,r)=\oplus_{i=l}^{r} a[i]$ $ g(l,r)=\ ...

  7. 计蒜客 38229.Distance on the tree-1.树链剖分(边权)+可持久化线段树(区间小于等于k的数的个数)+离散化+离线处理 or 2.树上第k大(主席树)+二分+离散化+在线查询 (The Preliminary Contest for ICPC China Nanchang National Invitational 南昌邀请赛网络赛)

    Distance on the tree DSM(Data Structure Master) once learned about tree when he was preparing for NO ...

  8. 2019ICPC南昌邀请赛网络赛 I. Max answer (单调栈+线段树/笛卡尔树)

    题目链接 题意:求一个序列的最大的(区间最小值*区间和) 线段树做法:用单调栈求出每个数两边比它大的左右边界,然后用线段树求出每段区间的和sum.最小前缀lsum.最小后缀rsum,枚举每个数a[i] ...

  9. 2019南昌邀请赛网络赛:J distance on the tree

    1000ms 262144K   DSM(Data Structure Master) once learned about tree when he was preparing for NOIP(N ...

随机推荐

  1. dos2unix命令详解

    基础命令学习目录首页 原文链接:https://blog.csdn.net/leedaning/article/details/53024290 使用git 的时候碰到git将unix换行符转换为wi ...

  2. js中 null, undefined, 0,空字符串,false,不全等比较

    null == undefined // true null == ''  // false null == 0 // false null == false // false undefined = ...

  3. 使用sass与compass合并雪碧图(二)

    上一篇文章介绍了怎样使用compass合并雪碧图,生成的icons.css文件中单位是px,PC端可以直接在html文件中使用,但在移动端,我们需要根据不同分辨率的屏幕,来缩放图片大小,显然使用px单 ...

  4. Scrum Meeting 8 -2014.11.14

    给开发加了个pdf信息提取优化任务. 弄了半天发现服务器也是个好东西.这周末可以和爬虫讨论整合的问题了. Member Today’s task Next task 林豪森 协助测试及服务器部署 协助 ...

  5. Chapter 3 软件项目管理

    软件项目具有产品的不可见性.项目的高度不确定性.软件过程的多变化性.软件人员的高流动性的显著特征.有效的软件项目管理集中于人员.产品.过程和项目四个方面.软件项目的生命周期有项目启动.项目规划.项目实 ...

  6. 1~n中1的和

    题目:给定一个十进制的正整数,写下从1开始,到N的所有整数,然后数一下其中出现“1”的个数: 要求:写一个函数f(n),返回1到n之间出现“1“的个数, 思路: 1.先判断这个数共多少位,假设为n位: ...

  7. HDU 3853 LOOPS 期望dp

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3853 LOOPS Time Limit: 15000/5000 MS (Java/Others)Me ...

  8. ansible的简单使用

    环境搭建跳过(暂无,这个以后再学习学习,不要在意这些细节) 首先,在环境搭建好后,用两台虚机来做测试,一台192.168.181.130做测试机,一台192.168.181.131为批量处理服务器 编 ...

  9. Python入门:条件控制

    条件控制其实就是if...else...(如果...条件是成立的,就做...:反之,就做...)的使用,其基本结构是: 具体看下面这个例子: def account_login(): # 定义函数 p ...

  10. Linux_Apache 安装

    1.下载依赖扩展 apr.apr-util.pcre(正则依赖) https://apr.apache.org/download.cgi#aprutil1 apr:http://mirrors.shu ...