• 20140705 testB DP


    testB

    输入文件: testB.in  输出文件testB.out 时限2000ms

    问题描述:

    方师傅有两个由数字组成的串 a1,a2,⋯,an 和 b1,b2,⋯,bm。 有一天,方师傅感到十分无聊因此他决定用这两个串来玩玩游戏。游戏规则十分简单,方师傅会进行一些操作,每个操作可能是以下两种操作之一:

    1.从a串选择一个a的非空前缀,再从b串选一个b的非空前缀。这两个前缀的最后一个元素必须相等,完成选择后把这两个前缀删除。

    2.删除两个串所有的元素。

    第一种操作会耗费e的能量值,并为方师傅增加一美分到他的电子账户中。第二种操作会耗费两个串的不完整度的能量。不完整度 = 两个串已经被删除的元素的数目。只有执行第二种操作后,方师傅才能从电子帐户中取出他的钱。

    刚开始时,方师傅有一个空的电子账户和s的能量,请问方师傅最多可以赚多少美分?注意,由于乐警官偷吃光了方师傅的士力架,导致方师傅无法补充能量,因此方师傅的能量任何时候都不能小于0。

    输入描述:

    第一行4个整数,n,m,s,e(1≤n,m≤10^5;1≤s≤3×10^5;10^3≤e≤10^4)。

    第二行n个整数,a1,a2⋯an.

    第三行m个整数,b1,b2⋯bm.

    1≤ai,bi≤10^5

    输出描述:

    输出一个整数,方师傅可以最多赚得的美分数目。

    样例输入1:

    5 5 100000 1000
    1 2 3 4 5
    3 2 4 5 1

    样例输出1:

    3
     

    样例输入2:

    3 4 3006 1000
    1 2 3
    1 2 4 3

    样例输出2:

    2


    先来吐槽一下数据-_-
    直接输出s/e竟然有80分
    我写的暴力竟然没有小数据T^T

    解题报告:
    首先若一定要删除一次a[i] , 假如a[i]=b[j]=b[k] j<k那么一定删除j而不是k。
    用普通的dp[i][j]表示A匹配到i,B匹配到j的最大能量一定不满足(MLE&&TLE)。可以换一种思路dp[i][j]表示A匹配到了i,获得美分为j时,B上一次匹配到的最早位置。由于j不会超过300,所以可以满足条件。

    转移每一次二分查找和当前a[i]匹配最近的那个b[j]值即可,可以预处理一个数组存放位置。

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <vector>
     4 #include <cstring>
     5 using namespace std;
     6 #define MAX_N 100010
     7 #define INF 0x3f3f3f
     8 
     9 int a[MAX_N],b[MAX_N];
    10 vector <int> l[MAX_N];
    11 int n,m,s,e;
    12 int dp[MAX_N][310];
    13 
    14 
    15 int main() {
    16     memset(dp,INF,sizeof(dp));
    17     scanf("%d%d%d%d",&n,&m,&s,&e);
    18     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    19     for (int i=1;i<=m;i++) {
    20         scanf("%d",&b[i]);
    21         l[b[i]].push_back(i);
    22     }
    23     int tot=s/e;
    24     int ans=0;
    25     dp[0][0]=0;
    26     for (int i=1;i<=n;i++) {
    27         dp[i][0]=0;
    28         for (int j=1;j<=tot;j++) {
    29             dp[i][j]=dp[i-1][j];
    30             int aa=upper_bound(l[a[i]].begin(),l[a[i]].end(),dp[i][j-1])-l[a[i]].begin();
    31             if (aa<l[a[i]].size()) {
    32                 dp[i][j]=min(dp[i][j],l[a[i]][aa]);
    33             }
    34             if (j>ans && j*e+i+dp[i][j]<=s) {
    35                 ans=j;
    36             }
    37         }
    38     }
    39     printf("%d",ans);
    40 }
    View Code
  • 相关阅读:
    有用的sql语句积累
    spring boot sso 学习资源
    notepad++ 常用快捷键
    artTemplate的使用总结
    ajax完整请求
    03 Mybatis框架---学习笔记1--框架的概念及优势
    02 Struts2框架----学习笔记2(了解一下,已过时)
    IDEA 获取类的相对路径和绝对路径
    01 Struts2框架学习(了解一下,已过时)
    喜马拉雅 FM 已购付费音频下载
  • 原文地址:https://www.cnblogs.com/fjmmm/p/3828492.html
Copyright © 2020-2023  润新知