hdu 5535 Cake 构造+记忆化搜索
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5355
题意:给定n与m,其中1<= n <= 1e5,2 <= m <= 10;问是否存在将1~n个数分成m组,使得每组的和相等;若存在输出m行,每行表示一组的值,否则输出NO;
ps:总共T<=1000组数据,还是挺大的;
思路:预判之后,若可能存在则直接以2m为周期,从大往小构造出和相等的m组,这样就可以将n的值缩小到2m~4m-2;因为当n = 4m-1时,再次减去一个周期,下一个讨论的右边界为2m-1,易知(2m-1)*2m/2/m是可以构造出符合的m个式子的;并且坑爹的是,出题人这次的常数系数不能太大,AC的代码运行了514ms,当把n 周期缩小处改为n > 4*m-1时,直接TLE了;在搜索中系数大了不止一倍;
dfs也是比较巧妙,需要加个start来单调查找每组的数据,是最终全部m组全部求完了再return true,并不是每组完成就直接return,这样还可以修改直接选择的错误;
判断一组完成了只是将参数值复原为原始值;还有需要使用dp优化,设置了define来简写;
- #include<bits/stdc++.h>
- using namespace std;
- #define rep0(i,l,r) for(int i = (l);i < (r);i++)
- #define rep1(i,l,r) for(int i = (l);i <= (r);i++)
- #define rep_0(i,r,l) for(int i = (r);i > (l);i--)
- #define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
- #define MS0(a) memset(a,0,sizeof(a))
- #define MS1(a) memset(a,-1,sizeof(a))
- #define MSi(a) memset(a,0x3f,sizeof(a))
- #define inf 0x3f3f3f3f
- #define lson l, m, rt << 1
- #define rson m+1, r, rt << 1|1
- #define lowbit(x) (x&(-x))
- typedef pair<int,int> PII;
- #define A first
- #define B second
- #define MK make_pair
- typedef long long ll;
- typedef unsigned int uint;
- template<typename T>
- void read1(T &m)
- {
- T x=,f=;char ch=getchar();
- while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
- while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
- m = x*f;
- }
- template<typename T>
- void read2(T &a,T &b){read1(a);read1(b);}
- template<typename T>
- void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);}
- template<typename T>
- void out(T a)
- {
- if(a>) out(a/);
- putchar(a%+'');
- }
- int i,j,k,n,m,l,r;
- const int N = 1e5+;
- int ans[][N],aux[][N],vs[],ave,board;
- int dp[][],rec[][][][];
- #define def rec[board][m]
- bool dfs(int tot,int id,int start)
- {
- if(tot == ave){id++;tot = ;start = ;} // 这是一项结束了,是另一项的开始;当然了只有全部结束时,才返回true;
- if(id == m){
- rep1(i,,board)if (!vs[i]){
- aux[id][++aux[id][]] = i;
- }
- return true;
- }
- rep1(i,start,board){
- if(tot+i > ave) return false;
- if(!vs[i]){
- vs[i] = ;
- aux[id][++aux[id][]] = i;
- if(dfs(tot+i,id,i+)) return true;
- vs[i] = ,aux[id][]--;
- }
- }
- return false;
- }
- bool solve(int top)
- {
- if(top >= *m-){
- for(int i = ,j = ;i <= m;i++,j++){
- ans[i][++ans[i][]] = top-*m++j;
- ans[i][++ans[i][]] = top-j;
- }
- return solve(top-*m);
- }
- else{
- ave = top*(top+)/m/;
- //printf("%d ",ave);
- board = top;
- if(dp[board][m] == ){
- if(dfs(,,)){
- dp[board][m] = ;
- rep1(i,,m)
- rep1(j,,aux[i][])
- def[i][j] = aux[i][j]; // define了
- }
- else dp[board][m] = -;
- }
- if(dp[board][m] == ) return true;
- return false;
- }
- }
- int main()
- {
- //freopen("data.txt","r",stdin);
- //freopen("out.txt","w",stdout);
- int T; read1(T);
- for(int kase = ;kase <= T;kase++){
- MS0(vs);
- rep1(i,,) ans[i][] = aux[i][] = ;
- read2(n,m);
- ll sum = 1LL*n*(n+)/;
- if(sum%m || sum/m < n || !solve(n)){
- puts("NO");
- continue;
- }
- puts("YES");
- rep1(i,,m){
- printf("%d",ans[i][]+def[i][]);
- rep1(j,,ans[i][])
- printf(" %d",ans[i][j]);
- rep1(j,,def[i][])
- printf(" %d",def[i][j]);
- puts("");
- }
- }
- return ;
- }
hdu 5535 Cake 构造+记忆化搜索的更多相关文章
- UVa 1629 Cake slicing (记忆化搜索)
题意:一个矩形蛋糕上有好多个樱桃,现在要做的就是切割最少的距离,切出矩形形状的小蛋糕,让每个蛋糕上都有一个樱桃,问最少切割距离是多少. 析:很容易知道是记忆化搜索,我们用dp[u][d][l][r]来 ...
- [HDU 1428]--漫步校园(记忆化搜索)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1428 漫步校园 Time Limit: 2000/1000 MS (Java/Others) M ...
- 牛客国庆集训派对Day2 F、平衡二叉树 【构造+记忆化搜索】
任意门:https://www.nowcoder.com/acm/contest/202/F 时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 1048576K,其他语言2097152K6 ...
- hdu 4597 Play Game(记忆化搜索)
题目链接:hdu 4597 Play Game 题目大意:给出两堆牌,仅仅能从最上和最下取,然后两个人轮流取,都依照自己最优的策略.问说第一个人对多的分值. 解题思路:记忆化搜索,状态出来就很水,dp ...
- hdu 4856 Tunnels (记忆化搜索)
Tunnels Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su ...
- HDU 4597 Play Game(记忆化搜索,深搜)
题目 //传说中的记忆化搜索,好吧,就是用深搜//多做题吧,,这个解法是搜来的,蛮好理解的 //题目大意:给出两堆牌,只能从最上和最下取,然后两个人轮流取,都按照自己最优的策略,//问说第一个人对多的 ...
- HDU 5001 概率DP || 记忆化搜索
2014 ACM/ICPC Asia Regional Anshan Online 给N个点,M条边组成的图,每一步能够从一个点走到相邻任一点,概率同样,问D步后没走到过每一个点的概率 概率DP 測 ...
- HDU 4597 Play Game (记忆化搜索博弈DP)
题意 给出2*n个数,分两列放置,每列n个,现在alice和bob两个人依次从任意一列的对头或队尾哪一个数,alice先拿,且两个人都想拿最多,问alice最后能拿到数字总和的最大值是多少. 思路 4 ...
- HDU 3779 Railroad(记忆化搜索)
Railroad Time Limit : 4000/2000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Total Subm ...
随机推荐
- canvas-7globleCompositeOperation2.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 超图(hypergraph)
超图是什么? 超图的本质特征在于它的超边,它可以连接两个以上的结点(包括两个).按这样的意义来说,我们所熟悉的普通图只是超图的一个特例而已,而超图则定义了一个更加宽泛的图. 超图的数学定义为:对于超图 ...
- 【PL/SQL练习】自定义异常
由用户自己定义1.定义异常名称,类型exception2.举出异常(raise excepttion)3.捕获异常 SQL> declare e_user_err exception; v_de ...
- Windows 7的100M隐藏分区
1.Windows 7的100MB的隐藏分区是Windows 7的活动分区,类似于Linux的/boot. 这其实有点类似Linux的做法,Linux在安装过程中可以专门分出一个100MB左右的分区作 ...
- 学习总结 java 异常
package com.hanqi.ec; public class Test1 { public static void main(String[] args) { int a = 10 , b = ...
- No.005 Longest Palindromic Substring
5. Longest Palindromic Substring Total Accepted: 120226 Total Submissions: 509522 Difficulty: Medium ...
- ionic cordova file download and load
1.先添加插件 cordova plugin add org.apache.cordova.file cordova plugin add org.apache.cordova.file-transf ...
- SQLServer转MYSQL的方法(连数据)
本次转换需要依赖使用工具Navicat Premium. 首先,将数据库移至本地SQLServer,我试过直接在局域网上其他SQLServer服务器上想转到本地Mysql好像有问题,想将远程数据库备份 ...
- SQL2005中使用identity_insert向自动增量字段中写入内
摘自: http://www.aspbc.com/tech/showtech.asp?id=1117 SQL2005以前的数据库是不允许向自动增量字段中写入内容的,ACCESS也不行,但在SQL200 ...
- linux 下wifi 功能的实现
一.嵌入式linux四件套配置 1.网卡选型的依据: a.网卡不能乱选,否则没戏.网卡的依据是,kernel的menuconfig -> device drivers -> network ...