zoukankan      html  css  js  c++  java
  • 一道题

    image


    这是学弟问我的一道题, 竟然是以前cf的题, 我大概想对了一多半吧, 如果和我队友一起的话应该是能够A掉的。。 首先两个数相乘是平方数, 那么把这个数质因数分解的话, 每个因数的幂一定是2的倍数, 假设一个因子是(a^{2i+1}), 那我们不妨看成(a^1), 当然对答案是没有影响的, 那么问题就变成, 分组后每组不能有相同的数字,那么我们就想到dp的做法。 设dp[i][j]表示前i个数, 改变j次最小的分组数。当然我们需要知道, 每个数前面改变i次所能达到的左端点, 我们记为l[i][j], 这个可以用双指针(O(nk))求出。转移方程的话就很简单。
    (dp[i][j] = min(dp[i][j], dp[l[i][q] - 1][j - q] + 1) (q≤j))

    点击查看代码
    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int INF = 0x3f3f3f3f;
    const int N = 1e5 + 10;
    const int M = 1e7 + 10;
    const int maxn = 3e3;
    
    template < typename T > inline void read(T &x) {
    	x = 0; T ff = 1, ch = getchar();
    	while (!isdigit(ch)) {
    		if (ch == '-') ff = -1;
    		ch = getchar();
    	}
    	while (isdigit(ch)) {
    		x = (x << 1) + (x << 3) + (ch ^ 48);
    		ch = getchar();
    	}
    	x *= ff;
    }
    
    vector < int > v;
    int n, k, a[N], dp[N][21], l[N][21];
    int cnt[M], vis[M];
    
    inline void pre() {
    	for (int i = 2; i <= maxn; ++i) {
    		if (!vis[i]) {
    			vis[i] = i;
    			v.push_back(i);
    		}
    		for (int j = 0; j < v.size(); ++j) {
    			if (v[j] > vis[i] || v[j] > maxn / i) break;
    			vis[i * v[j]] = v[j];
    		}
    	}
    }
    
    inline void work() {
    	for (int i = 1; i <= n; ++i) {
    		int cnt = 1;		
    		for (int j = 0; j < v.size(); ++j) {
    			int y = v[j], w = 0;
    			while (a[i] % y == 0) a[i] /= y, ++w;
    			if (w & 1) cnt *= y;
    			if (a[i] == 1) break;
    		}
    		a[i] *= cnt;
    	}
    }
    
    int main() {
    //	freopen("team.in", "r", stdin);
    //	freopen("team.out", "w", stdout);
    	read(n), read(k);
    	for (int i = 1; i <= n; ++i) read(a[i]);
    	pre();
    	work();
    	for (int i = 0; i <= k; ++i) {
    		int L = 1, sum = 0;
    		for (int j = 1; j <= n; ++j) {
    			++cnt[a[j]];
    			if (cnt[a[j]] > 1) ++sum;
    			while (sum > i) {
    				--cnt[a[L]];
    				if (cnt[a[L]]) --sum;
    				++L;
    			}
    			l[j][i] = L;
    		} 
    		while (L <= n) --cnt[a[L]], ++L; 
    	}
    	memset(dp, 0x3f, sizeof(dp));
    	for (int i = 0; i <= k; ++i) dp[0][i] = 0;
    	for (int i = 1; i <= n; ++i) 
    		for (int j = 0; j <= k; ++j) 
    			for (int q = 0; q <= j; ++q) 
    				dp[i][j] = min(dp[i][j], dp[l[i][q] - 1][j - q] + 1);
    	int ans = INF;
    	for (int i = 0; i <= k; ++i) ans = min(ans, dp[n][i]);	
    	printf("%d
    ", ans);
    	return 0;
    }
    
    
  • 相关阅读:
    maven-eclipse-plugin downloadSources downloadJavadocs
    maven的resources插件
    Intellij IDEA 添加项目依赖
    git 代码统计
    windows查看局域网ip
    Spring Boot学习笔记---Spring Boot 基础及使用idea搭建项目
    git push fatal: HttpRequestException encountered. An error occurred while sending the request
    ubuntu15中tomcat开机自动启动
    ubuntu15 设置静态ip && centos7设置静态ip
    ubuntu15.10 下时间同步
  • 原文地址:https://www.cnblogs.com/AK-ls/p/15515342.html
Copyright © 2011-2022 走看看