zoukankan      html  css  js  c++  java
  • 51Nod 1201 整数划分 (经典dp)

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1201

    题意不多说了。

    dp[i][j]表示i这个数划分成j个数的情况数。

    dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1]

    前者表示将i - 1划分为j个数,然后j个数都+1 还是不重复

    后者表示将i - 1划分为j - 1个数,然后j - 1个数都+1,再加上1这个数

    普通的dp是n^2的,但是可以发现1 + 2 + ... + m = n , (1 + m)*m = n * 2,j只要遍历sqrt(n * 2)个就好了。所以复杂度为n*sqrt(n*2)

     1 //#pragma comment(linker, "/STACK:102400000, 102400000")
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <cstdlib>
     5 #include <cstring>
     6 #include <cstdio>
     7 #include <vector>
     8 #include <cmath>
     9 #include <ctime>
    10 #include <list>
    11 #include <set>
    12 #include <map>
    13 using namespace std;
    14 typedef long long LL;
    15 typedef pair <int, int> P;
    16 const int N = 5e4 + 5;
    17 int dp[N][350], mod = 1e9 + 7;
    18 
    19 int main()
    20 {
    21     int n;
    22     while(~scanf("%d", &n)) {
    23         memset(dp, 0, sizeof(dp));
    24         dp[0][0] = 1;
    25         for(int i = 1; i <= n; ++i) {
    26             for(int j = 1; j*j <= i*2; ++j) {
    27                 dp[i][j] = (dp[i - j][j] + dp[i - j][j - 1]) % mod;
    28             }
    29         }
    30         int ans = 0;
    31         for(int i = 1; i <= n; ++i) {
    32             ans = (ans + dp[n][i]) % mod;
    33         }
    34         printf("%d
    ", ans);
    35     }
    36     return 0;
    37 }
  • 相关阅读:
    E. You Are Given Some Strings...
    神奇函数
    AC自动机再加强版
    AC自动机2
    AC自动机
    three arrays
    permutation 2
    string matching
    permutation 1
    equation
  • 原文地址:https://www.cnblogs.com/Recoder/p/5907176.html
Copyright © 2011-2022 走看看