码迷,mamicode.com
首页 > 其他好文 > 详细

JNday6-pm

时间:2017-11-02 21:58:12      阅读:184      评论:0      收藏:0      [点我收藏+]

标签:从后往前   include   cst   sum   stdin   pac   stdout   ace   str   

T1
这道题一开始的思路就是错误的。。
对于任意数m,我们枚举 <= m的数,实质上就是
将m的二进制(二进制表示,从前到后分别是从低位到高位表示)
的每一位1当做0,这一位之前的数所有数为任意
那么对于这道题,将负数变为0,构造一个前缀和,
从后往前枚举,当这一位是1时,我们用 前面的数全选和
后面的数只选为1的位上的数 来更新ans,然后扫完就是最终的ans

T2
二分答案 DP
二分两个数之间的差的最大值
F[i]表示i不改变的最小修改的元素个数
f[i] = min(f[j] +(i-j-1), i-1) abs(A[j]-A[i]) < 二分出来的答案*(i-j)

T3
题目本质
遇到A加y遇到B减x 求序列中相等的数的最远距离
同时可以考虑分块

 

T1函数最值

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>

using namespace std;
const int maxn = 200000;

int n;
char c;
int a[maxn],b[maxn];
long long s[maxn];

int main() 
{
    scanf("%d",&n);
    for (int i = 1; i <= n; i ++){
        scanf("%d", &a[i]);
        if (a[i] < 0) a[i] = 0;
    }
    for (int i = 1; i <= n; i ++) scanf("%1d", &b[i]);
    s[0] = 0;
    for (int i = 1; i <= n; i ++) s[i] = s[i - 1] + a[i];
    long long ans = 0,sum = 0;
    for (int i = n; i >= 1; i --){
        if (b[i] == 1){
            ans = max(ans, sum + s[i - 1]);
            sum += a[i];
        }
    }
    printf("%lld",ans);
    return 0;
}
/*
6
5 6 7 8 9 10
000101
*/

T2函数最值2

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
using namespace std;
int n,k;
int a[2000],f[2000];
int ok(int x)
{
   f[1] = 0;
   int ans = n;
   for (int i = 2; i<=n;i++)
   {
     f[i] = i-1;
     for (int j = 1; j<i;j++)
     if (abs(a[i]-a[j])<=((long long)x*(i-j))) f[i] = min(f[i],f[j]+(i-j-1));
     ans = min(ans,f[i]+n-i);
   }
   return ans<=k;
}
int main()
{
  freopen("minimum.in","r",stdin);
  freopen("minimum.out","w",stdout);
  scanf("%d%d",&n,&k);
  for (int i = 1; i<=n;i++)
    scanf("%d",&a[i]);
  int l = 0, r = 1000000001;
  for (; r-l>1; )
  {
     int mid = (l+r)/2;
     if (ok(mid)) r = mid; else l = mid;
  }
  if (ok(l)) printf("%d\n",l); else printf("%d\n",r);
  return 0;
}

T3序列

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <ctime>
using namespace std;
const int maxn = 200000;
const int len = 400;
int n, A, B,m;
int a[maxn],b[maxn],l[maxn],r[maxn],lb[maxn],tot;
int answer[300][300];
int rt[300][maxn], lt[300][maxn],d[maxn];
//int root[maxn*len], ll[maxn*len], rr[maxn*len],data[maxn*len];
int find(int x) {
    for (int l = 0, r = m; l < r;) {
        int mid = (l + r) / 2;
        if (b[mid] == x) return mid;
        if (b[mid]>x) r = mid;
        else l = mid + 1;
    }
    return -1;
}
int main() {
    double ti = clock();
    freopen("sequence.in", "r", stdin);
    freopen("sequence.out", "w", stdout);
    scanf("%d%d%d", &n, &A, &B);
    a[0] = 0;
    for (int i = 1; i <= n; i++) {
        char c;
        for (scanf(" %c", &c); c != A && c != B; scanf(" %c", &c));
        if (c == A) a[i] = a[i - 1] + B;
        else a[i] = a[i - 1] - A;
    }
    for (int i = 0; i <= n; i++) b[i] = a[i];
    sort(b, b + n + 1);
    m = unique(b, b + n + 1) - b;
    for (int i = 0; i <= n; i++) {
        a[i] = find(a[i]);
        if (a[i] == -1) {
            printf("???\n");
            return 0;
        }
    }
    n++;
    int k = n / len;
    for (int i = 0; i <= k; i++) {
        int ans = 0;
        tot++;
        for (int j = i*len; j < n; j++) {
            if (j%len == 0) {
                answer[i][j / len] = ans;
            }
            if (lb[a[j]] != tot) {
                lb[a[j]] = tot;
                l[a[j]] = j;
            }
            ans = max(ans, j - l[a[j]]);
        }
    }
    for (int i = 0; i < n; i++) r[i] = -1;
    for (int i = 0; i < n; i++) {
        r[a[i]] = i;
        if (i%len == len - 1) {
            int tmp = i / len;
            for (int j = 0; j < n; j++)
                rt[tmp][j] = r[j];
        }
    }
    for (int i = 0; i < n; i++) l[i] = -1;
    for (int i = n - 1; i >= 0; i--) {
        l[a[i]] = i;
        if (i%len == 0) {
            int tmp = i / len;
            for (int j = 0; j < n; j++)
                lt[tmp][j] = l[j];
        }
    }
    int q;
    scanf("%d", &q);
    int ans = 0;
    for (; q; q--) {
        int L, R;
        scanf("%d%d", &L, &R);
        L--;
        int kl = L / len, kr = R / len;
        ans = 0;
        if (kl == kr) {
            tot++;
            for (int i = L; i <= R; i++) {
                if (lb[a[i]] != tot) {
                    lb[a[i]] = tot;
                    l[a[i]] = i;
                }
                ans = max(ans, i - l[a[i]]);
            }
        } else {
            ans = answer[kl + 1][kr];
            tot++;
            int tmp = min(n, (kl + 1)*len);
            for (int i = L; i < tmp; i++) {
                if (lb[a[i]] != tot) {
                    lb[a[i]] = tot;
                    l[a[i]] = i;
                    ans = max(ans, rt[kr - 1][a[i]] - i);
                }
            }
            tmp = min(R + 1, n);
            for (int i = kr*len; i < tmp; i++) {
                if (lb[a[i]] != tot) {
                    if (lt[kl + 1][a[i]] != -1) ans = max(ans, i - lt[kl + 1][a[i]]);
                } else ans = max(ans, i - l[a[i]]);
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}

 

JNday6-pm

标签:从后往前   include   cst   sum   stdin   pac   stdout   ace   str   

原文地址:http://www.cnblogs.com/lyqlyq/p/7774611.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!