• Codeforces Round #297 (Div. 2)E. Anya and Cubes 折半搜索


    题目连接:

    http://codeforces.com/contest/525/problem/E

    题意:

    n个数,k个魔法棒,s为所求的数,然后让你找有多少种方法,能够使的这n个数之和为s,其中一个魔法棒可以使的一个数变成他的阶乘。

    题解:

    第一种:http://blog.csdn.net/weizhuwyzc000/article/details/50043151
    对于每一层,有3种决策: 不选这个数, 选择这个数, 选择这个数的阶乘。 递归深度最大25, 时间复杂度O(3^25), 太大了, 要想办法降低时间复杂度。 还记得之前的简化版吗? 我们在四个集合中每个集合选择一个数字相加,问是否等于一个数S, 我们的方法是预处理三个集合中所有的情况,然后二分。 该题也可以采取相同的策略: 进行两次dfs, 每次递归深度n/2,这样就成功将复杂度降低到O((3^13)*log(3^13)) 。 这是理论上界, 事实上这里面有很多重复的,时间复杂度并没有那么高。

    第二种:http://www.cnblogs.com/qscqesze/p/4371851.html
    折半搜索
    对于每一个数,都有三种策略,拿,不拿,使用魔法棒
    那么我们就直接折半搜索然后扔进一个map里面,然后就查询就好啦
    13^3*12^3=3 796 416;
    复杂度算的刚刚好呀= = (没看懂怎么算的

    学到了 折半搜索降低复杂度 这个折半的意思是预先算出一半的结果,再从后一半找到sum-ans1。
    还有就是map的运用 按first从小到大默认排序,如果first是结构体, 可以在结构体中写优先级的函数,map就会自动排序啦

    代码一:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 #define mem(a) memset(a,0,sizeof(a))
     5 #define mp(x,y) make_pair(x,y)
     6 const int INF = 0x3f3f3f3f;
     7 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
     8 inline ll read(){
     9     ll x=0,f=1;char ch=getchar();
    10     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    11     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    12     return x*f;
    13 }
    14 //////////////////////////////////////////////////////////////////////////
    15 const int maxn = 1e5+10;
    16 ll n,k,s;
    17 ll a[30],ans;
    18 ll p[30];
    19 
    20 struct node{
    21     ll sum, y;
    22     node(ll ss=0, ll kk=0):sum(ss), y(kk) {}
    23     bool operator < (const node& rhs) const {
    24         if(sum==rhs.sum) return y<rhs.y;
    25         return sum < rhs.sum;
    26     }
    27 };
    28 
    29 map<node,int> mp;
    30 map<node,int>::iterator it;
    31 
    32 void dfs1(int nn,int kk,ll ss){
    33     if(k < kk) return ;
    34     if(ss > s) return ;
    35     if(nn > n/2){
    36         node t(ss,kk);
    37         mp[t]++;
    38         return ;
    39     }
    40 
    41     dfs1(nn+1,kk,ss);
    42     dfs1(nn+1,kk,ss+a[nn]);
    43     if(a[nn] <= 20) dfs1(nn+1,kk+1,ss+p[a[nn]]);
    44 }
    45 
    46 void dfs2(int nn,int kk,ll ss){
    47     if(k < kk) return ;
    48     if(ss > s) return ;
    49     if(nn > n){
    50         it = mp.lower_bound(node(s-ss,0));
    51         for( ; it!=mp.end(); it++){
    52             if(it->first.sum==s-ss && k-it->first.y >= kk) ans += it->second;
    53             if(it->first.sum != s-ss) break;
    54         }
    55         return ;
    56     }
    57 
    58     dfs2(nn+1,kk,ss);
    59     dfs2(nn+1,kk,ss+a[nn]);
    60     if(a[nn] <= 20) dfs2(nn+1,kk+1,ss+p[a[nn]]);
    61 }
    62 
    63 int main(){
    64     p[1] = 1;
    65     for(int i=2; i<=20; i++)
    66         p[i] = i*p[i-1];
    67 
    68     n = read(), k = read(), s = read();
    69     for(int i=1; i<=n; i++)
    70         a[i] = read();
    71 
    72     int mid = n/2;
    73     dfs1(1,0,0);
    74     dfs2(mid+1,0,0);
    75 
    76     cout << ans << endl;
    77 
    78     return 0;
    79 }

    代码二:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 #define mem(a) memset(a,0,sizeof(a))
     5 #define mp(x,y) make_pair(x,y)
     6 const int INF = 0x3f3f3f3f;
     7 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
     8 inline ll read(){
     9     ll x=0,f=1;char ch=getchar();
    10     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    11     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    12     return x*f;
    13 }
    14 //////////////////////////////////////////////////////////////////////////
    15 const int maxn = 1e6+10;
    16 
    17 struct node{
    18     ll sum,key;
    19 }bef[maxn];
    20 ll p[30],cubes[30];
    21 ll n,k,s,cnt,ans;
    22 map<ll,ll> mp[30];
    23 map<ll,ll>::iterator it;
    24 
    25 void dfs1(ll nn,ll kk,ll ss){
    26     if(ss > s) return ;
    27     if(kk > k) return ;
    28     if(nn > n/2){
    29         bef[++cnt].sum = ss;
    30         bef[cnt].key = kk;
    31         return ;
    32     }
    33     dfs1(nn+1,kk,ss);
    34     dfs1(nn+1,kk,ss+cubes[nn]);
    35     if(cubes[nn] <= 20) dfs1(nn+1,kk+1,ss+p[cubes[nn]]);
    36 }
    37 
    38 void dfs2(ll nn,ll kk,ll ss){
    39     if(ss > s) return ;
    40     if(kk > k) return ;
    41     if(nn > n){
    42         mp[kk][ss]++;
    43         return ;
    44     }
    45     dfs2(nn+1,kk,ss);
    46     dfs2(nn+1,kk,ss+cubes[nn]);
    47     if(cubes[nn] <= 20) dfs2(nn+1,kk+1,ss+p[cubes[nn]]);
    48 }
    49 
    50 int main(){
    51     n = read(), k = read(), s = read();
    52     for(int i=1; i<=n; i++)
    53         cubes[i] = read();
    54     p[1] = 1;
    55     for(int i=2; i<=20; i++)
    56         p[i] = i*p[i-1];
    57 
    58     dfs1(1,0,0);
    59     dfs2(n/2+1,0,0);
    60 
    61     ans = 0;
    62     for(int i=1; i<=cnt; i++)
    63         for(int j=0; j<=k-bef[i].key; j++)
    64             ans += mp[j][s-bef[i].sum];
    65 
    66     cout << ans << endl;
    67 
    68     return 0;
    69 }
  • 相关阅读:
    题解 [CF891C] Envy
    题解 [BZOJ4710] 分特产
    题解 [BZOJ2159] Crash的文明世界
    题解 [BZOJ4144] Petrol
    #leetcode刷题之路1-两数之和
    week 7 文件操作与模板
    coursera 北京大学 程序设计与算法 专项课程 STL week8 list
    coursera 北京大学 程序设计与算法 专项课程 完美覆盖
    JSTL标签库不起作用的解决方案 .(转)
    javax.servlet.jsp.PageContext.getELContext()Ljavax/el/ELContext解决办法(转)
  • 原文地址:https://www.cnblogs.com/yxg123123/p/6827693.html
Copyright © 2020-2023  润新知