• 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
    没有梦想,何谈远方
  • 相关阅读:
    周记
    读书笔记
    我是一只IT小小鸟
    回车键完全替代模拟鼠标单击事件
    去除Flexgrid表格的隔行底色为白的样式
    Flexgrid中的sortable设为false的时候abbr属性也不存在的原因及解决办法
    Flexigrid列之间的拖拉线条在某些浏览器中不能很好地与栏目边缘重合解决方法介绍
    用基于openssl产生的密钥实现PHP和.NET端的RSA加解密互通
    CSS3轮播图
    淘宝放大镜
  • 原文地址:https://www.cnblogs.com/zyue/p/4372922.html
Copyright © 2020-2023  润新知