hdu4982 Goffi and Squary Partition (DFS解法)
http://acm.hdu.edu.cn/showproblem.php?pid=4982
Goffi and Squary PartitionTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 308 Accepted Submission(s): 106Problem 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]
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
|
题意:给出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解法)的更多相关文章
- hdu 4982 Goffi and Squary Partition
Goffi and Squary Partition Time Limit: / MS (Java/Others) Memory Limit: / K (Java/Others) Total Subm ...
- HDU 4982 Goffi and Squary Partition(推理)
HDU 4982 Goffi and Squary Partition 思路:直接从全然平方数往下找,然后推断是否能构造出该全然平方数,假设能够就是yes,假设都不行就是no.注意构造时候的推断,因为 ...
- 【HDOJ】4982 Goffi and Squary Partition
题意就是整数划分,选出和为n的K个整数,其中K-1个数的和为完全平方数S.选择整数时需要从1,2,3..连续选择,当选择整数与n-S相等时,需要跳过n-S,即选择n-S+1.如此选择K-2个数,从而可 ...
- Goffi and Squary Partition
题意: 给你N和K,问能否将N拆分成K个互不相同的正整数,并且其中K-1个数的和为完全平方数. PS:这道题目原来是要求输出一种可行方案的,所以下面题解是按照输出方案的思想搞的. 分析: 我们尝试枚举 ...
- BestCoder6 1002 Goffi and Squary Partition(hdu 4982) 解题报告
题目链接:http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?pid=1002&cid=530 (格式有一点点问题,直接粘 ...
- UVALive 6450 Social Advertising DFS解法
题意:一些人有朋友关系,在某个人的社交网站上投放广告可以被所有该人的直接朋友看到,问最小投放多少个广告使给出的人都看到广告.(n<=20) 解法:看到n的范围可以想到用二进制数表示每个人被覆盖与 ...
- HDU 1312 Red and Black --- 入门搜索 DFS解法
HDU 1312 题目大意: 一个地图里面有三种元素,分别为"@",".","#",其中@为人的起始位置,"#"可以想象 ...
- HDU1150Machine Schedule(二分图最大匹配的DFS解法)
题目大意就是说有两台机器,分别有n,m种模式可以调节,有k个工作,某一个工作i可以在第一台机器的a[i]模式下或第二台机器的b[i]模式下工作,两台机器的初始模式为0,问如何分配这K件工作使得两台机器 ...
- 分酒问题(DFS解法)
题目大概是这样: 已知有三个容量分别为3千克.5千克和8千克的并且是没有刻度的酒瓶,3千克和5千克的瓶子均装满了酒,而8千克的瓶子为空.现要求仅用这三个酒瓶将这些酒均分为两个4千克并分别装入5千克和8 ...
随机推荐
- ASCII码对照表
最近做东西常用到,所以就这里和收藏一下,需要注意的是10和13,在windows中文本java会把回车解释成是1310两个字节,在linux下面是10一个字节. 下面是将两个文件读成了二进制之后的结果 ...
- jquery插件-表单验证插件-rules
ruels方法 1说明:查看.新增.移除一个表单控件的验证规则 2使用: 表单控件.rules(); 参数: rules() 返回元素的验证规则 rules('add',rules) 增加验证规则 r ...
- POJ1185 炮兵阵地
题目描述 Description 司令部的将军们打算在N × M的网格地图上部署他们的炮兵部队.一个N × M的地图由N行M列组成,地图的每一格可能是山地(用"H"表示),也可能是 ...
- 轻量级Web API实现,带接口界面的Jayrock JsonRPC接口组件升级版
升级功能如下: 1.增加模块名称.输入参数.输出参数注释 2.增加Sign验证.输入数据解密.输出数据解密重写方法 3.增加集成Demo规范 4.增加模块分类.接口快速定位.接口调用说明.接口输入输出 ...
- SVN+Jenkins或CCNET环境部署图
目前来说比较常用的方案:
- MongoDB安装,配置
安装 cd /usr/local/srcwget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel62-3.2.6.tgztar z ...
- 在Swift中使用JavaScript的方法和技巧
本文作者Nate Cook是一位独立的Web及移动应用开发者,是继Mattt大神之后NSHipster的主要维护者,也是非常知名活跃的Swift博主,并且还是支持自动生成Swift在线文档的Swift ...
- MOOCULUS微积分-2: 数列与级数学习笔记 1. Sequences
此课程(MOOCULUS-2 "Sequences and Series")由Ohio State University于2014年在Coursera平台讲授. PDF格式教材下载 ...
- CSS的4种引入方式及优先级
第一:css的四种引入方式 1.行内样式 最直接最简单的一种,直接对HTML标签使用style="",例如: <p style="color:#F00; " ...
- BZOJ1568: [JSOI2008]Blue Mary开公司
可以平衡树或线段树维护斜率来做. 还有一种线段树直接打标记的做法: 线段树每个节点存一条线段作为标记,打标记时如果已有标记,则把占优区间小的那个线段下放. #include<cstdio> ...