zoukankan      html  css  js  c++  java
  • 【CSP-S 2019】D2T2 划分

    Description

    传送门

    Solution

    算法1 12pts

    指数算法随便乱搞。

    算法2 36pts

    (O(n^3))dp。

    (f_{i,j})表示以位置(j)结尾,上一个决策点为(j)时的最小值。

    转移也是显而易见的:

    (s_i=sum limits_{j=1}^{i} a_j),即前缀和。

    [f_{i,j}=f_{j,k}+(s_i-s_j)^2,其中 s_i-s_j ge s_j-s_k ]

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    
    inline ll ty() {
    	char ch = getchar(); ll x = 0, f = 1;
    	while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
    	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    	return x * f;
    }
    
    const int _ = 5000 + 10;
    int n, type;
    ll A[_], sum[_], f[_][_], ans;
    
    inline ll _2(ll x) { return x * x; }
    
    int main() {
    	n = ty(), type = ty();
    	for (int i = 1; i <= n; ++i) {
    		A[i] = ty();
    		sum[i] = sum[i - 1] + A[i];
    		// cout << sum[i] << endl;
    	}
    	memset(f, 0x3f, sizeof(f));
    	ans = f[0][0];
    	for (int i = 1; i <= n; ++i) {
    		for (int j = 1; j <= i; ++j) {
    			if (j == 1) f[i][j] = _2(sum[i]);
    			else
    				for (int k = 1; k < j; ++k)
    					if (sum[i] - sum[j - 1] >= sum[j - 1] - sum[k - 1])
    						f[i][j] = min(f[i][j], f[j - 1][k] + _2(sum[i] - sum[j - 1]));
    		}
    	}
    	
    	for (int i = 1; i <= n; ++i) ans = min(ans, f[n][i]);
    	printf("%lld
    ", ans);
    	return 0;
    }
    

    算法3 64pts

    (O(n^2))dp。这个因为我太蒻了,所以不会写。大概思路就是

    “可以固定(j),发现在移动(i)的过程中,(k)也在移动,满足一个单调性,然后我们维护一个(f_{j,k})的最小值就可以了”

    算法4 84/100pts

    据说通过打表可以发现证明链接,当最后一段在满足有解的情况下和最小时,答案最优。

    因此可以设(g_i)表示到位置(i)时,在有解的情况下值最小的上一个决策点的位置,即

    [g_i = max limits_{j=0}^{i-1}j, s.t. s_i-s_j ge s_j-s_{g_j} ]

    稍微移个项就可以得到

    [s_i ge 2s_j-s_{g_j} ]

    显然这是单调的,于是用一个单调队列维护即可。

    Code

    #include <bits/stdc++.h>
    using namespace std;
    
    inline int ty() {
    	char ch = getchar(); int x = 0, f = 1;
    	while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
    	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    	return x * f;
    }
    
    typedef long long ll;
    const int _ = 5e5 + 10;
    int n, type, a[_], q[_], g[_];
    ll sum[_], ans;
    
    inline ll calc(int j) { return 2ll * sum[j] - sum[g[j]]; }
    inline ll _2(const ll &x) { return x * x; }
    
    int main() {
    #ifndef ONLINE_JUDGE
    	freopen("divide.in", "r", stdin);
    	freopen("divide.out", "w", stdout);
    #endif
    	n = ty(), type = ty();
    	for (int i = 1; i <= n; ++i) a[i] = ty(), sum[i] = sum[i - 1] + a[i];
    	int h = 1, t = 1;
    	for (int i = 1; i <= n; ++i) {
    		while (h < t && calc(q[h + 1]) <= sum[i]) ++h;
    		g[i] = q[h];
    		while (h < t && calc(q[t]) >= calc(i)) --t;
    		q[++t] = i;
    	}
    	int now = n;
    	while (now) {
    		ans = ans + _2(sum[now] - sum[g[now]]);
    		now = g[now];
    	}
    	printf("%lld
    ", ans);
    	return 0;
    }
    
    既然选择了远方,便只顾风雨兼程。
  • 相关阅读:
    虚拟主机导入MySQL出现Unknown character set: ‘utf8mb4’
    解决导入MySQL数据库提示"Unknown character set: 'utf8mb4'"错误
    在js中怎样获得checkbox里选中的多个值?
    CSharp设计模式读书笔记(0):设计原则(学习难度:★★☆☆☆,使用频率:★★★★★)
    how to install maven and svn plugin into eclipse 3.6
    三个月不编程,能力下降80%
    maven管理的struts2spring3mybatisfreemarker框架整合
    Wiki: JavaHL for subversion & ubuntu lucid
    重装系统要装的库包 for ubuntu lucid
    Q for Eclipse is an Apache Maven plugin for the Eclipse IDE
  • 原文地址:https://www.cnblogs.com/newbielyx/p/12031507.html
Copyright © 2011-2022 走看看