标签:贪心
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4982
解析:
题意:
给你N和K,问能否将N拆分成K个互不相同的正整数,并且其中K-1个数的和为完全平方数
实际上,一拿到题目,我先想了下这里会不会存在负数或者0,后来经过几次华丽丽的WA之后发现,这题确实不用考虑到非正数。但是还是想吐槽一下,这个题目的意思也有点儿太不明晰了。。。
再说回题目来,我们枚举所有的完全平方数i*i,然后看能否将他拆成k-1个数,并且用不到n-i*i。所以这里我们用到贪心+部分特殊处理。
我们尝试尽量用 1,2,3...这些连续自然数来构造,如果 n-i*i 出现在这些数中,那么将 n-i*i 移除,再新加一个数。如果这样都不能拆分成 k-1 个数,那么这个完全平方数( i*i) 肯定不行。
由于我们不需要输出某一个具体答案,所以也就不需要dfs那么高深费劲的解法了,在这里我们只需要找到一个可能性就可以直接跳出循环了。
找到可能性的等价事件就是排除所以不可能的事件。
那么我们看看有哪些不可能构造的情况吧!
1.前k-1个数的和就已经超过n,那可定就不可能用k个数字来表示n了;
2.在举例每个完全平方数的时候:
2.1 前k-1个数的和大于完全平方数;
2.2 n-i*i在前k-1个数里面,那么必然构造完全平方数的时候不会用到n-i*i而最小要用到数字k,然而前k个 数之和减去n-i*i大于完全平方数(i*i);
2.3 如果n-i*i==k,并且前k-1个数之和加上1等于完全平方数,那么后者必然也会用到k,所以这种情况也不成立。(当然前k-1个数之和加上t(t>1)等于完全平方数,就可以不必用到数字k,其他的情况也是如此)
代码:
/* ID:muller8 Name: 4982 Goffi and Squary Partition Reference: 贪心 */ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <vector> #include <cmath> using namespace std; #define MAXN 10005 #define INF 1e9 int main(){ int n,k; while(~scanf("%d%d", &n, &k)){ bool flag; if((k+1)*k/2>n) flag = false; else{ int i; flag = false; for(i=1; i*i<n; ++i){ int left = n-i*i; if(k*(k-1)/2>i*i) continue; if((left<=k-1)&&(k*(k+1)/2-left>i*i)) continue; if(left==k&&k*(k-1)/2+1==i*i) continue; flag = true; break; } } printf("%s\n", flag?"YES":"NO"); } return 0; }
HDU 4982 Goffi and Squary Partition(BestCoder Round #6 1002)
标签:贪心
原文地址:http://blog.csdn.net/mullerwch/article/details/38821911