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. Linux操作系统PS命令详细解析

    要对系统中进程进行监测控制,用 ps 命令满足你. /bin/ps ps 是显示瞬间行程的状态,并不动态连续:如果想对进程运行时间监控,应该用 top 工具. kill 用于杀死进程. ======= ...

  2. osquery An Operating System Instrumentation Framewor

    catalog . Getting Started . install guide for OS X and Linux . Features Overview . Logging . query e ...

  3. [iOS 主要框架的总结]

    原文地址:http://blog.csdn.net/GooHong/article/details/28911301 在iOS中框架是一个目录,包含了共享资源库,用于访问该资源库中储存的代码的头文件, ...

  4. 如何保持自己 fork 的项目和原始项目同步

    首先先通过 github 的 web 页面 fork 目标的项目 前提是自己已经设置好了git,并且配置了相应的权限 然后使用git clone命令在本地克隆自己 fork 的项目: git clon ...

  5. 加州大学伯克利分校Stat2.3x Inference 统计推断学习笔记: Section 1 Estimating unknown parameters

    Stat2.3x Inference(统计推断)课程由加州大学伯克利分校(University of California, Berkeley)于2014年在edX平台讲授. PDF笔记下载(Acad ...

  6. [JavaEE]理解ThreadLocal

    转http://www.iteye.com/topic/103804 首先,ThreadLocal 不是用来解决共享对象的多线程访问问题的,一般情况下,通过ThreadLocal.set() 到线程中 ...

  7. ffmpeg]ffmpeg使用参数的中文说明

    基本选项: -formats 输出所有可用格式 -f fmt 指定格式(音频或视频格式) -i filename 指定输入文件名,在linux下当然也能指定:0.0(屏幕录制)或摄像头 -y 覆盖已有 ...

  8. 系统配置 之:远程桌面连接(win7系统)

    本文包括两部分: 1.配置远程桌面连接 2.解决[远程桌面连接不上] 一.远程桌面连接设置 [远程桌面连接配置] Win7系统下的远程桌面连接设置,如果是其他系统或 Win8 及其以上系统,也可作为参 ...

  9. 获取URL的code的参数的值

    1.获取URL的code的参数的值 需求说明:现在有URL为http://www.bdqn.cn/index.php?code=sdR4,请使用字符串对象的属性和方法来获取code的值,并把其指都转化 ...

  10. 【Phylab2.0】Alpha版本发布说明

    新版本特性 更多的实验 Part Phylab2.0[Alpha] Phylab1.0 1011 1010113 缺失 1011 1010212 缺失 1021 1020113 1021 102021 ...