• LOJ#6502. 「雅礼集训 2018 Day4」Divide 题解


    题目链接

    考虑把数列(w_i)重新排列,使得新数列(w_i)满足对于任意 i , 所有的 (w_{j(j<i)} + w_i geq m) 或者所有的 (w_{j(j<i)} + w_i < m,)然后(O(n^2) DP) 就容易了。

    如何构造?

    先把(w_i)从小到大排序。一开始答案序列(ans)为空。

    如果(w_1+w_n geq m,)那么对于所有 (w_{i(i<n)},w_{i(i<n)}+w_n geq m,)可以把 (w_n) 放到(ans)的末尾,并删去 (w_n)

    否则,对于所有(w_{i(i<n)},w_{i(i<n)}+w_n < m,)可以把 (w_1) 放到(ans)的末尾,并删去 (w_1)

    那么就可以(O(nlog n)) 构造了。

    复杂度(O(n^2))

    code :

    #include <bits/stdc++.h>
    using namespace std;
    template <typename T> void read(T &x){
    	static char ch; x = 0,ch = getchar();
    	while (!isdigit(ch)) ch = getchar();
    	while (isdigit(ch)) x = x * 10 + ch - '0',ch = getchar();
    }
    inline void write(int x){if (x > 9) write(x/10); putchar(x%10+'0'); }
    const int N = 2005,P = 1e9 + 7;
    int n,m,a[N];
    inline void build(){
    	static int w[N];
    	int i,len = n+1,l,r;
    	for (i = 1; i <= n; ++i) w[i] = a[i]; sort(w+1,w+n+1);
    	l = 1,r = n;
    	while (l <= r){
    		if (w[l] + w[r] >= m) a[--len] = w[r],--r;
    		else a[--len] = w[l],++l;
    	}
    }
    inline void upd(int &x,int v){ x = (x+v>=P)?(x+v-P):(x+v); }
    int mx[N][N],f[N][N];
    int main(){
    	int i,j,v,t;
    	int is;
    	read(n),read(m);
    	for (i = 1; i <= n; ++i) read(a[i]);
    	build();
    	for (i = 0; i <= n; ++i) for (j = 0; j <= n; ++j) mx[i][j] = -1;
    	mx[1][0] = mx[1][1] = 0,f[1][0] = f[1][1] = 1;
    	for (i = 1; i < n; ++i){
    		is = a[i+1] + a[i] >= m ? 1 : 0;
    		for (j = 0; j <= i; ++j) if (mx[i][j] > -1){
    			v = f[i][j],t = mx[i][j] + is * (i-j);
    			if (t == mx[i+1][j+1]) upd(f[i+1][j+1],v);
    			else if (t > mx[i+1][j+1]) mx[i+1][j+1] = t,f[i+1][j+1] = v;
    			t = mx[i][j] + is * j;
    			if (t == mx[i+1][j]) upd(f[i+1][j],v);
    			else if (t > mx[i+1][j]) mx[i+1][j] = t,f[i+1][j] = v;
    		}
    	}
    	int Mx = 0,ans = 0;
    	for (i = 0; i <= n; ++i)
    		if (mx[n][i] > Mx) Mx = mx[n][i],ans = f[n][i];
    		else if (mx[n][i] == Mx) upd(ans,f[n][i]);
    	cout << Mx <<' ' <<ans << '
    ';
    	return 0;
    }
    
  • 相关阅读:
    printf和sprintf
    操作数、运算符、表达式
    全自动加法机
    Ascll、GB2312、Ansi
    数组
    循环
    编程命名规范
    浮点数及缺陷
    Android编码规范
    RGB着色对照表
  • 原文地址:https://www.cnblogs.com/s-r-f/p/13628597.html
Copyright © 2020-2023  润新知