zoukankan      html  css  js  c++  java
  • [51mod 1201]整数划分 dp

    题目

    将N分为若干个不同整数的和,问有多少种不同的划分方式,例如:n = 6,{6} {1,5} {2,4} {1,2,3},共4种。由于数据较大,输出Mod 10^9 + 7的结果即可。

     

    很容易想到01背包,由于要求每个整数都不同,故每个整数就可以看作物品

    f[i][j]表示在1~i的整数中选择若干个,和为j的方案数

    f[i][j]=f[i-1][j]+f[i-1][j-i](取/不取i)

    然而n<=50000,无法解决

     

    至此就束手无策了,看了题解之后不得不感叹这个神奇的状态转移方式

    首先需要想到的是:和为n的整数个数,最多也只能为sqrt(n*2);(证法先留个坑) 

    f[i][j]表示用了i个数字,和为j的方案数

    则将转移情况分为两种:

    1)取i,f[i][j]=f[i-1][j-i];

    2)不取i,将f[i][j-i]每个数都加1

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

    还有一个类似的状态转移poj1664

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cmath>
     5 using namespace std;
     6 
     7 const int M=1e9+7;
     8 const int Maxn=50000;
     9 int n;
    10 int f[320][Maxn];
    11 int main(){
    12     scanf("%d",&n);
    13     memset(f,0,sizeof(f));
    14     f[0][0]=1;
    15     int ULine=int(sqrt(2*n));
    16     for (int i=1;i<=ULine+1;i++){
    17         for (int j=i;j<=n;j++){
    18             f[i][j]=(f[i-1][j-i]+f[i][j-i])%M; 
    19         }
    20     }
    21     int ans=0;
    22     for (int i=1;i<=ULine;i++)
    23       ans=(ans+f[i][n])%M;
    24     printf("%d",ans);
    25     return 0;
    26 }
    View Code
  • 相关阅读:
    【转自百度贴吧】把古诗最后三个字改为“日了狗”,看谁最有才!
    计划!
    [BZOJ2424][HAOI2010]订货
    [BZOJ1026][SCOI2009]windy数
    【作文】高考之外
    [AYYZVijos1761]运输问题
    [BZOJ1047][HAOI2007]理想的正方形
    [NOIP2015]代码
    新的独立博客
    不忘初心,方得始终——NOIP2016前的感悟
  • 原文地址:https://www.cnblogs.com/vincent-hwh/p/6725176.html
Copyright © 2011-2022 走看看