BestCoder Round #6 B

http://acm.hdu.edu.cn/showproblem.php?pid=4982

Goffi and Squary Partition

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 308    Accepted Submission(s): 106

Problem Description
Recently, Goffi is interested in squary partition of integers.
A set \(X\) of \(k\) distinct positive integers is called squary partition of \(n\) if and only if it satisfies the following conditions: [ol]

  • the sum of \(k\) positive integers is equal to \(n\)
  • one of the subsets of \(X\) containing \(k - 1\) numbers sums up to a square of integer.[/ol] For example, a set {1, 5, 6, 10} is a squary partition of 22 because 1 + 5 + 6 + 10 = 22 and 1 + 5 + 10 = 16 = 4 × 4.
    Goffi wants to know, for some integers \(n\) and \(k\), whether there exists a squary partition of \(n\) to \(k\) distinct positive integers.
 
Input
Input contains multiple test cases (less than 10000). For each test case, there's one line containing two integers \(n\) and \(k\) (\(2 \le n \le 200000, 2 \le k \le 30\)).
 
Output
For each case, if there exists a squary partition of \(n\) to \(k\) distinct positive integers, output "YES" in a line. Otherwise, output "NO".
 
Sample Input
2 2
4 2
22 4
 
Sample Output
NO
YES
YES
 
Source
 
Recommend
heyang   |   We have carefully selected several similar problems for you:  4984 4983 4981 4980 4979

题意:给出n和k,求k个不同的正整数,使其中k-1个数能组成平方数,k个数的和为n。有解输出YES,无解输出NO。

题解:从大到小枚举小于n的平方数,剪枝搜索是否有解。

先判一下是不是1~k这最小的k个数加起来都超过n,这种情况肯定不可能,真去搜一遍的话太费时间了,还是特判掉比较好。

if((+k)*k/>n)return ;

枚举平方数,进入搜索:

     t=sqrt(1.0*n);
if(t*t==n)t--;
for(i=t; i>=; i--) {
int lost=i*i;
Remove(n-lost);
if(dfs(lost,,R[n]))return ;
Resume(n-lost);
}

↑(这个在函数里,return 1是有解。)

这题每个数只用一次,所以枚举一个数,下个数可以从这个数+1开始枚举。我使用了DancingLinks那种超碉的结构,不过其实只用一个used[]就好了……

比赛的时候这样就能过了,因为n大的时候很容易就找到解,dfs不耗多长时间。不过今天一看居然加强了数据,会TLE,所以我们来加个剪枝:

当枚举第x个数时,剩下(k-x+1)个数,枚举i为当前的数,如果i+ (i+1)+(i+2)+...+(i+k-x)这以i开头的最小的k-x+1个数都大于剩下的数了,就不用继续枚举i了。

等差数列求和,(i + i+(k-x))*(k-x+1)/2 > lost,搞一搞可以把 i 移出来,得到i的最大值。

DFS代码:

 bool dfs(const int &lost,const int &x,const int &now) {
if(x>k) {
if(lost==)
return ;
else return ;
}
if(lost<=)return ;
if(x!=k) {
int maxi=((lost+lost)/(k-x+)-(k-x))/;///剩下的大于i的最小的(k-x+1)个数加起来超的话就跳
maxi=min(maxi,n-);
for(int i=now; i<=maxi; i=R[i]) {
Remove(i);
if(dfs(lost-i,x+,R[i]))return ;
Resume(i);
}
} else {
if(L[R[lost]]==lost) {
Remove(lost);
if(dfs(,x+,R[lost]))return ;
Resume(lost);
}
}
return ;
}

(这题的正解好像是各种情况都考虑一下,直接几个if就判出来了……我是不太懂)(还有官方题解说平方数只用枚举最大的那个就行,可是8 2这组数据,最大的平方数是4,然后就逗乐啊……虽然好像只有这一组数据有问题)

全代码:

 //#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<stack>
#include<queue>
using namespace std;
#define ll long long
#define usll unsigned ll
#define mz(array) memset(array, 0, sizeof(array))
#define minf(array) memset(array, 0x3f, sizeof(array))
#define REP(i,n) for(i=0;i<(n);i++)
#define FOR(i,x,n) for(i=(x);i<=(n);i++)
#define RD(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define WN(x) prllf("%d\n",x);
#define RE freopen("D.in","r",stdin)
#define WE freopen("1biao.out","w",stdout)
#define mp make_pair
#define pb push_back const int maxn=;
int L[maxn],R[maxn];
inline void Remove(int x) {
L[R[x]]=L[x];
R[L[x]]=R[x];
} inline void Resume(int x) {
L[R[x]]=x;
R[L[x]]=x;
} int n,k; bool dfs(const int &lost,const int &x,const int &now) {
if(x>k) {
if(lost==)
return ;
else return ;
}
if(lost<=)return ;
if(x!=k) {
int maxi=((lost+lost)/(k-x+)-(k-x))/;///剩下的大于i的最小的(k-x+1)个数加起来超的话就跳
maxi=min(maxi,n-);
for(int i=now; i<=maxi; i=R[i]) {
Remove(i);
if(dfs(lost-i,x+,R[i]))return ;
Resume(i);
}
} else {
if(L[R[lost]]==lost) {
Remove(lost);
if(dfs(,x+,R[lost]))return ;
Resume(lost);
}
}
return ;
} bool farm(int _n,int _k) {
int t;
int i,j;
n=_n;
k=_k;
if((+k)*k/>n)return ;
for(i=; i<=n; i++) {
L[i]=i-;
R[i-]=i;
}
L[]=n;
R[n]=;
t=sqrt(1.0*n);
if(t*t==n)t--;
for(i=t; i>=; i--) {
int lost=i*i;
Remove(n-lost);
if(dfs(lost,,R[n]))return ;
Resume(n-lost);
}
return ;
} int main() {
int i;
int n,k;
while(scanf("%d%d",&n,&k)!=EOF) {
if(farm(n,k))printf("YES\n");
else printf("NO\n");
// for(i=0;i<r;i++)
// printf("%d ",b[i]);
// puts("");
}
return ;
}

hdu4982 Goffi and Squary Partition (DFS解法)的更多相关文章

  1. hdu 4982 Goffi and Squary Partition

    Goffi and Squary Partition Time Limit: / MS (Java/Others) Memory Limit: / K (Java/Others) Total Subm ...

  2. HDU 4982 Goffi and Squary Partition(推理)

    HDU 4982 Goffi and Squary Partition 思路:直接从全然平方数往下找,然后推断是否能构造出该全然平方数,假设能够就是yes,假设都不行就是no.注意构造时候的推断,因为 ...

  3. 【HDOJ】4982 Goffi and Squary Partition

    题意就是整数划分,选出和为n的K个整数,其中K-1个数的和为完全平方数S.选择整数时需要从1,2,3..连续选择,当选择整数与n-S相等时,需要跳过n-S,即选择n-S+1.如此选择K-2个数,从而可 ...

  4. Goffi and Squary Partition

    题意: 给你N和K,问能否将N拆分成K个互不相同的正整数,并且其中K-1个数的和为完全平方数. PS:这道题目原来是要求输出一种可行方案的,所以下面题解是按照输出方案的思想搞的. 分析: 我们尝试枚举 ...

  5. BestCoder6 1002 Goffi and Squary Partition(hdu 4982) 解题报告

    题目链接:http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?pid=1002&cid=530 (格式有一点点问题,直接粘 ...

  6. UVALive 6450 Social Advertising DFS解法

    题意:一些人有朋友关系,在某个人的社交网站上投放广告可以被所有该人的直接朋友看到,问最小投放多少个广告使给出的人都看到广告.(n<=20) 解法:看到n的范围可以想到用二进制数表示每个人被覆盖与 ...

  7. HDU 1312 Red and Black --- 入门搜索 DFS解法

    HDU 1312 题目大意: 一个地图里面有三种元素,分别为"@",".","#",其中@为人的起始位置,"#"可以想象 ...

  8. HDU1150Machine Schedule(二分图最大匹配的DFS解法)

    题目大意就是说有两台机器,分别有n,m种模式可以调节,有k个工作,某一个工作i可以在第一台机器的a[i]模式下或第二台机器的b[i]模式下工作,两台机器的初始模式为0,问如何分配这K件工作使得两台机器 ...

  9. 分酒问题(DFS解法)

    题目大概是这样: 已知有三个容量分别为3千克.5千克和8千克的并且是没有刻度的酒瓶,3千克和5千克的瓶子均装满了酒,而8千克的瓶子为空.现要求仅用这三个酒瓶将这些酒均分为两个4千克并分别装入5千克和8 ...

随机推荐

  1. 【BZOJ-3638&3272&3267&3502】k-Maximum Subsequence Sum 费用流构图 + 线段树手动增广

    3638: Cf172 k-Maximum Subsequence Sum Time Limit: 50 Sec  Memory Limit: 256 MBSubmit: 174  Solved: 9 ...

  2. 微信小程序一步步搭建商城系列-01-开篇

    1.小程序介绍 小程序是一种不需要下载安装即可使用的应用,它实现了应用“触手可及”的梦想,用户扫一扫或者搜一下即可打开应用.也体现了“用完即走”的理念,用户不用关心是否安装太多应用的问题.应用将无处不 ...

  3. BZOJ1853 [Scoi2010]幸运数字

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...

  4. Windows批处理以服务的方式启动解决思路(ShadowsockR注册成Windows Service)

    我以ShadowsockR的server启动来解释: 由于这东西是python,如果要启动,可以写一个批处理(python.exe server.py)来启动,但是我观察发现启动的时候是附带pytho ...

  5. Oracle技术嘉年华

    只有把一件事情做好,才会获得更多的机会! 短期的努力,成效并不明显,但是自己的成长一定能够感受到! 嘉年华的收获: 遗憾: 总结: 展望:

  6. uva12716 gcd

    题意:给出N,1<=b<=a<=N,求满足gcd(a,b)=a xor b的pair (a,b)的个数 有个重要的结论:若gcd(a,b)=a xor b=c,那么b=a-c 如果一 ...

  7. hdu 5147 树状数组

    题意:求满足a<b<c<d,A[a]<A[b],A[c]<A[d]的所有四元组(a,b,c,d)的个数 看到逆序对顺序对之类的问题一开始想到了曾经用归并排序求逆序对,结果 ...

  8. 使用LaTeX编辑数学公式

    首先在博客园的页首html里添加以下代码: <script type="text/x-mathjax-config"> MathJax.Hub.Config({ tex ...

  9. django_restframework_angularjs

    用Django Rest Framework和AngularJS开始你的项目 作者:Kevin Stone原帖:Getting Started with Django Rest Framework a ...

  10. CSS3定位和浮动详解

    本文为大家分享CSS3定位和浮动的基础概念,与使用方法,供大家参考,具体内容如下 一.定位 1. css定位: 改变元素在页面上的位置 2. css定位机制: 普通流: 浮动: 绝对布局: 3. cs ...