zoukankan      html  css  js  c++  java
  • 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来简写;

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define rep0(i,l,r) for(int i = (l);i < (r);i++)
      4 #define rep1(i,l,r) for(int i = (l);i <= (r);i++)
      5 #define rep_0(i,r,l) for(int i = (r);i > (l);i--)
      6 #define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
      7 #define MS0(a) memset(a,0,sizeof(a))
      8 #define MS1(a) memset(a,-1,sizeof(a))
      9 #define MSi(a) memset(a,0x3f,sizeof(a))
     10 #define inf 0x3f3f3f3f
     11 #define lson l, m, rt << 1
     12 #define rson m+1, r, rt << 1|1
     13 #define lowbit(x) (x&(-x))
     14 typedef pair<int,int> PII;
     15 #define A first
     16 #define B second
     17 #define MK make_pair
     18 typedef long long ll;
     19 typedef unsigned int uint;
     20 template<typename T>
     21 void read1(T &m)
     22 {
     23     T x=0,f=1;char ch=getchar();
     24     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     25     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     26     m = x*f;
     27 }
     28 template<typename T>
     29 void read2(T &a,T &b){read1(a);read1(b);}
     30 template<typename T>
     31 void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);}
     32 template<typename T>
     33 void out(T a)
     34 {
     35     if(a>9) out(a/10);
     36     putchar(a%10+'0');
     37 }
     38 int i,j,k,n,m,l,r;
     39 const int N = 1e5+7;
     40 int ans[11][N],aux[11][N],vs[44],ave,board;
     41 int dp[50][11],rec[50][11][11][50];
     42 #define def rec[board][m]
     43 bool dfs(int tot,int id,int start)
     44 {
     45     if(tot == ave){id++;tot = 0;start = 1;} // 这是一项结束了,是另一项的开始;当然了只有全部结束时,才返回true;
     46     if(id == m){
     47         rep1(i,1,board)if (!vs[i]){
     48             aux[id][++aux[id][0]] = i;
     49         }
     50         return true;
     51     }
     52     rep1(i,start,board){
     53         if(tot+i > ave) return false;
     54         if(!vs[i]){
     55             vs[i] = 1;
     56             aux[id][++aux[id][0]] = i;
     57             if(dfs(tot+i,id,i+1))  return true;
     58             vs[i] = 0,aux[id][0]--;
     59         }
     60     }
     61     return false;
     62 }
     63 bool solve(int top)
     64 {
     65     if(top >= 4*m-1){
     66         for(int i = 1,j = 0;i <= m;i++,j++){
     67             ans[i][++ans[i][0]] = top-2*m+1+j;
     68             ans[i][++ans[i][0]] = top-j;
     69         }
     70        return  solve(top-2*m);
     71     }
     72     else{
     73         ave = top*(top+1)/m/2;
     74         //printf("%d ",ave);
     75         board = top;
     76         if(dp[board][m] == 0){
     77             if(dfs(0,1,1)){
     78                 dp[board][m] = 1;
     79                 rep1(i,1,m)
     80                     rep1(j,0,aux[i][0])
     81                         def[i][j] = aux[i][j]; // define了
     82             }
     83             else dp[board][m] = -1;
     84         }
     85         if(dp[board][m] == 1) return true;
     86         return false;
     87     }
     88 }
     89 int main()
     90 {
     91     //freopen("data.txt","r",stdin);
     92     //freopen("out.txt","w",stdout);
     93     int T; read1(T);
     94     for(int kase = 1;kase <= T;kase++){
     95         MS0(vs);
     96         rep1(i,0,10) ans[i][0] = aux[i][0] = 0;
     97         read2(n,m);
     98         ll sum = 1LL*n*(n+1)/2;
     99         if(sum%m || sum/m < n || !solve(n)){
    100             puts("NO");
    101             continue;
    102         }
    103         puts("YES");
    104         rep1(i,1,m){
    105             printf("%d",ans[i][0]+def[i][0]);
    106             rep1(j,1,ans[i][0])
    107                 printf(" %d",ans[i][j]);
    108             rep1(j,1,def[i][0])
    109                 printf(" %d",def[i][j]);
    110             puts("");
    111         }
    112     }
    113     return 0;
    114 }
  • 相关阅读:
    (转)Xargs用法详解
    (转)运维老鸟教你安装centos6.5如何选择安装包
    (转)正则表达式与三剑客的使用技巧
    php OAuth服务端编写
    前端工程精粹(一):静态资源版本更新与缓存
    静态资源打包:一个javescript 的src引用多个文件,一个link引用多个CSS文件
    ie,cookie,域名与下划线
    HTML中css和js链接中的版本号
    PHP 优化详解
    jqury插件编写
  • 原文地址:https://www.cnblogs.com/hxer/p/5491742.html
Copyright © 2011-2022 走看看