zoukankan      html  css  js  c++  java
  • 方程的解数[NOI2001](meet in the middle)

      题目链接:http://cogs.pro:8080/cogs/problem/problem.php?pid=304

     

      题解:

      直接搜索(枚举)复杂度为O(m^n),可以用meet in the middle降为(sqrt(m^n))。

         什么是meet in the middle呢?

      就是把整个搜索范围分成两部分分开搜索。

      就这道题而言,我们把他分成两部分之后,可以算出每个部分的可能取值集合,然后再统计从两个集合中各取一个且和为0的方案数即可。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define LL long long
     6 #define RI register int
     7 using namespace std;
     8 const int INF = 0x7ffffff ;
     9 const int N = 10 ;
    10 const int M = 3500000 ;
    11 
    12 inline int read() {
    13     int k = 0 , f = 1 ; char c = getchar() ;
    14     for( ; !isdigit(c) ; c = getchar())
    15       if(c == '-') f = -1 ;
    16     for( ; isdigit(c) ; c = getchar())
    17       k = k*10 + c-'0' ;
    18     return k*f ;
    19 }
    20 int n, m, rk1, rk2, lv, ans ; int p[N], k[N], p1[N], k1[N], res1[M], res2[M] ;
    21 
    22 inline int poww(int a,int b) {
    23     int base = a, rres = 1 ;
    24     while(b) {
    25         if(b&1) rres *= base ;
    26         base *= base ; b >>= 1 ;
    27     }
    28     return rres ;
    29 }
    30 void dfs(int now,int res,int *a,int &rk) {
    31     if(now > lv) {
    32         a[++rk] = res ; return ;
    33     }
    34     for(int i=1;i<=m;i++) {
    35 //        printf("xxx
    ") ;
    36         dfs(now+1,res+k1[now]*poww(i,p1[now]),a,rk) ;
    37     }
    38 }
    39 inline void work() {
    40     int j = rk2 ;
    41     sort(res1+1,res1+rk1+1) ; sort(res2+1,res2+rk2+1) ;
    42     for(int i=1;i<=rk1;i++) {
    43         while(res1[i]+res2[j] > 0 && j) j-- ;
    44         if(j <= 0) break ;
    45         if(res1[i]+res2[j] < 0) continue ;
    46         int cnt1 = 1, cnt2 = 1 ;
    47         while(res1[i] == res1[i+1] && i < rk1) i++, cnt1++ ;
    48         while(res2[j] == res2[j-1] && j > 1) j--, cnt2++ ;
    49         ans += cnt1*cnt2 ;
    50     }
    51 }
    52 
    53 int main() {
    54 //    freopen("equation1.in","r",stdin) ;
    55 //    freopen("equation1.out","w",stdout) ;
    56     n = read(), m = read() ;
    57     for(int i=1;i<=n;i++) {
    58         k[i] = read(), p[i] = read() ;
    59     }
    60     lv = n>>1 ;
    61     for(int i=1;i<=lv;i++) k1[i] = k[i], p1[i] = p[i] ;
    62     dfs(1,0,res1,rk1) ;
    63     for(int i=1;i<=n-lv;i++) k1[i] = k[i+lv], p1[i] = p[i+lv] ;
    64     lv = (n+1)>>1 ;
    65     dfs(1,0,res2,rk2) ;
    66     work() ;
    67     printf("%d",ans) ;
    68     return 0 ;
    69 }
  • 相关阅读:
    关于ThreadLocal
    二月份推荐的书籍
    《编写高质量代码:改善Java程序的151个建议》笔记
    Oracle中定义package以及存储过程的使用
    不同系统平台下Java默认的安装路径
    WebSphere数据源配置
    Dedication(转)
    Upgrading to Java 8——第二章 Method References(方法引用)
    Upgrading to Java 8——第一章 Lambda表达式
    Multi-catch
  • 原文地址:https://www.cnblogs.com/zub23333/p/8618698.html
Copyright © 2011-2022 走看看