zoukankan      html  css  js  c++  java
  • Codeforces 525E Anya and Cubes

    题意:给你n(25)个数,任选几个数 ,你最多可以对任选的几个数中的 K个数进行操作,操作是将 这个数变为它的阶乘,你选出来的数经过操作以后 等于 s的种类数有多少。

    解题思路:看到这题的时候没什么思路,想想水一发dp  ,dp[i][j][k]<map>,就想到了这个四维的DP,但是显然这是会挂掉的。因为情况太多了,最多有 3^n种。

    那么需要是什么方法呢。那就是折半了,因为我们只需要找到一个值, 而全部DP的话会产生太多的值了,而这大部分值都不是我们需要的。所以就把n个数分成两堆去处理,然后用中间值凑出s,这样复杂度就会少很多.

    解题代码:

     1 // File Name: e.cpp
     2 // Author: darkdream
     3 // Created Time: 2015年03月27日 星期五 01时21分34秒
     4 
     5 #include<vector>
     6 #include<list>
     7 #include<map>
     8 #include<set>
     9 #include<deque>
    10 #include<stack>
    11 #include<bitset>
    12 #include<algorithm>
    13 #include<functional>
    14 #include<numeric>
    15 #include<utility>
    16 #include<sstream>
    17 #include<iostream>
    18 #include<iomanip>
    19 #include<cstdio>
    20 #include<cmath>
    21 #include<cstdlib>
    22 #include<cstring>
    23 #include<ctime>
    24 #define LL long long
    25 
    26 using namespace std;
    27 int n ,m ;
    28 LL s ; 
    29 LL a[100];
    30 LL b[100];
    31 map<int,map<LL,LL> > mpa;
    32 map<int,map<LL,LL> > mpb;
    33 map<LL,LL>::iterator tt;
    34 int li;
    35 void dfs(int p ,int k,LL v,map<int,map<LL,LL> > &tmp)
    36 {
    37     //printf("%d %d %I64d
    ",p,k,v);
    38     if(k > m)
    39         return;
    40     if(p == li + 1)
    41     {
    42       tmp[k][v] += 1 ;
    43       return;
    44     }
    45     if(v + a[p] <= s)
    46         dfs(p+1,k,v+a[p],tmp);
    47     if(a[p] <= 18 && v + b[p] <= s)
    48         dfs(p+1,k+1,v+b[p],tmp);
    49     dfs(p+1,k,v,tmp);
    50 }
    51 int main(){
    52     scanf("%d %d %I64d",&n,&m,&s);
    53     for(int i = 1;i <= n;i ++)
    54     {
    55        scanf("%I64d",&a[i]);
    56     }
    57     sort(a+1,a+1+n);
    58     for(int i = 1;i <= n;i ++)
    59     {
    60        if(a[i] <= 18)
    61        {
    62          b[i] = 1; 
    63          for(int j = 1;j <= a[i]; j ++)
    64          {
    65            b[i] *= j;
    66          }
    67        }
    68     }
    69      li = n/2; 
    70     dfs(1,0,0,mpa);
    71     li = n; 
    72     //puts("***");
    73     dfs(n/2+1,0,0,mpb);
    74     LL sum = 0 ; 
    75     for(int i = 0 ;i <= m;i ++)
    76     {
    77         for(int j = 0 ;j + i <= m;j ++)
    78         {
    79            for(tt = mpa[i].begin(); tt != mpa[i].end();tt++)
    80            {
    81               sum += (mpb[j][s - tt->first]) * (tt->second);
    82     //          printf("***%d %I64d %I64d %I64d
    ",j,s-tt->first,mpb[j][s-tt->first],tt->second);
    83            }
    84         }
    85     }
    86     printf("%I64d
    ",sum);
    87     return 0;
    88 }
    View Code
    没有梦想,何谈远方
  • 相关阅读:
    Win10 VMware虚拟机无法打开内核设备“\.Globalvmx86“
    搜索算法总结
    经典排序算法
    Markdown Test
    PAT L2-020 功夫传人【BFS】
    PAT l2-018 多项式A除以多项式B 【多项式+模拟】
    PAT l2-010 排座位 【并查集】
    二叉树的前中后序遍历关系 【非原创】
    PAT L2-005. 集合相似度 【stl set】
    PAT L2-004. 这是二叉搜索树吗?【前序遍历转化为后序遍历】
  • 原文地址:https://www.cnblogs.com/zyue/p/4372922.html
Copyright © 2011-2022 走看看