zoukankan      html  css  js  c++  java
  • 2018.10.17校内模拟赛:T2神光

    题面:pdf

    首先排序,二分,然后怎么判定是否可行。

    最简单的思路是,dp[i][j][k],到第i个,用了j次红光,k次绿光,前i个点都选上了,是否可行。然后转移就行。

    然后考试的时候就想到这了,往后没想到。于是贪心,乱搞,和n^3dp拍了几千组随机数据。然后,一共90。其中贪心可得80。

    上面的dp中,结果只能是0/1,于是可以考虑减掉一维,让结果表示一维。

    n^2 dp:感觉挺奇妙的。f[i][j]红的用了i次,绿的用了j次,最远到什么位置。dp[i][j]=max ( P[dp[i-1][j]+1], Q[dp[i][j-1]+1] )。其中 P[k]表示使用一次红光,能从第 k 座法坛向右(正向为右)连续摧毁到第几座,Q[k]表示使用一次绿光,能从第k座法坛向右连续摧毁到第几座。 P和Q数组可以通过预处理得到。

    其他的思路:f[i][j]到i,用了j次红光的时候,最少的绿光次数。

    代码:

     1 /*
     2 * @Author: mjt
     3 * @Date:   2018-10-17 16:16:28
     4 * @Last Modified by:   mjt
     5 * @Last Modified time: 2018-10-17 16:40:30
     6 */
     7 #include<cstdio>
     8 #include<algorithm>
     9 #include<cstring>
    10 #include<cmath>
    11 #include<iostream>
    12 #include<cctype>
    13 #include<set>
    14 #include<vector>
    15 #include<queue>
    16 #include<map>
    17 #define fi(s) freopen(s,"r",stdin);
    18 #define fo(s) freopen(s,"w",stdout);
    19 using namespace std;
    20 typedef long long LL;
    21 
    22 inline int read() {
    23     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
    24     for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
    25 }
    26 
    27 const int N = 2005;
    28 
    29 int a[N], P[N], Q[N], f[N][N], n, R, G;
    30 
    31 bool check(int x) {
    32     memset(f, 0, sizeof(f));
    33     memset(P, 0, sizeof(P));
    34     memset(Q, 0, sizeof(Q));
    35     for (int i=1; i<=n; ++i) {
    36         for (int j=i; j<=n; ++j) {
    37             if (a[j] - a[i] + 1 <= x) P[i] = j;
    38             if (a[j] - a[i] + 1 <= x + x) Q[i] = j;
    39         }
    40     }
    41     P[n + 1] = Q[n + 1] = n;
    42     for (int i=0; i<=R; ++i)
    43         for (int j=0; j<=G; ++j) {
    44             if (i) f[i][j] = max(f[i][j], P[f[i - 1][j] + 1]);
    45             if (j) f[i][j] = max(f[i][j], Q[f[i][j - 1] + 1]);
    46         }
    47     return f[R][G] == n;
    48 }
    49 
    50 int main() {
    51     n = read(), R = read(), G = read();
    52     for (int i=1; i<=n; ++i) a[i] = read();
    53     sort(a + 1, a + n + 1);
    54     if (R + G >= n) {
    55         cout << 1; return 0;
    56     }
    57     int L = 1, R = a[n] - a[1] + 1, ans = R;
    58     while (L <= R) {
    59         int mid = (L + R) >> 1;
    60         if (check(mid)) ans = mid, R = mid - 1;
    61         else L = mid + 1;
    62     }
    63     cout << ans;
    64     return 0;
    65 }
  • 相关阅读:
    nodejs async waterfull 小白向
    nodejs async series 小白向
    MySQL 分区介绍总结
    cocos2d-x 一些实用的函数
    LeetCode(61)-Valid Palindrome
    ganglia错误解决
    (6)uboot具体解释——关闭缓存和mmu
    Linux下设置MySQL不区分大写和小写
    火狐与IE的7个JavaScript差异
    商业研究(8):汽车交通
  • 原文地址:https://www.cnblogs.com/mjtcn/p/9805212.html
Copyright © 2011-2022 走看看