zoukankan      html  css  js  c++  java
  • HDU 4477 HDOJ Cut the rope II

    http://acm.hdu.edu.cn/showproblem.php?pid=4477

    题目意思:

      给你一个长度为n的线段,要求至少分成两段,使得每段的长度各不相同。问分解的方案数。

    首先考虑,若分解成k段,则n的值至少为1+2+3+4+...+k=(k+1)*k/2

    所以本题k的最大值为315

    考虑dp[k][n]表示长度为n的线段分解成k段的方案数。

    其中分为两种情况

      k段均大于一,则将每段的长度减1后,与dp[k][n-k]的方案数相同。

      k段中有一段是1,则去掉这段长度为1的,有k-1段,且长度均大于一,与dp[k-1][n-k]方案数相同,这是k>2的情况。特殊的,k=2时,n=1,2无解为0,n>2方案为(1,n-1),即1。

    代码:

     1 #include<cstdio>
     2 using namespace std;
     3 const int K=316,N=50000,m=1000000;
     4 int ans[N+10],s,dp[2][N+10];
     5 int main()
     6 {
     7     for(int i=3;i<=N;i++)
     8         ans[i]=dp[0][i]=dp[0][i-2]+1;
     9     for(int k=3;k<K;k++){
    10         int *p1=dp[k&1],*p2=dp[(k+1)&1];
    11         for(int i=k*(k+1)/2 - 1;i>0;i--)p1[i]=0;
    12         for(int i=k*(k+1)/2;i<=N;i++){
    13             p1[i]=p1[i-k]+p2[i-k];
    14             if(p1[i]>=m) p1[i]-=m;
    15             ans[i]+=p1[i];
    16             if(ans[i]>=m) ans[i]-=m;
    17         }
    18     }
    19     int T,n;
    20     scanf("%d",&T);
    21     while(T--){
    22         //scanf("%d",&n);
    23         printf("%d %d\n",T,ans[T]);
    24     }
    25     return 0;
    26 }
  • 相关阅读:
    爬虫防止浏览器防止debug处理
    php
    代码日记
    Linux定时任务
    Linux 三剑客(Awk、Sed、Grep)
    golang中使用ETCD
    golang中使用mysql数据库
    golang中使用Redis
    Linux进阶知识和命令
    Linux核心命令使用方法
  • 原文地址:https://www.cnblogs.com/hundundm/p/2808086.html
Copyright © 2011-2022 走看看