zoukankan      html  css  js  c++  java
  • 递推关系的运用加简单DP【UVA11137Ingenuous Cubrency】-------2015年1月27日

    一:题意描述

    本题就是求立方数之和。输入正整数n,求将n写成若干个正整数的立方和有多少种方法?

    二:问题分析

    本题主要的难点就是确定状态。我们可以建立多段图。节点(i,j)表示“使用不超过i的整数的立方,累加和为j“这个状态。设d(i,j)表示为从(0,0)到(i,j)的路径条数,最终答案

    是d(21,n)。对于这个图而言,每一个节点(i,j)都只能从当前节点(i,j)到达节点(i+1,a*(j+1)^3+j)(a为j+a*(j+1)^3<maxn的常数)所以我们可以写出如下代码:

    #include<iostream>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    using namespace std;
    #define MAXI 21
    #define  MAXN 10000+5
    long long d[MAXI+1][MAXN];
    int main()
    {
        int n;
        memset(d,0,sizeof(d));
        d[0][0]=1;
        for(int i=1;i<=MAXI;i++)
        {
            for(int j=0;j<=MAXN;j++)
            {
                for(int a=0;j+a*i*i*i<=MAXN;a++)
                    d[i][j+a*i*i*i]+=d[i-1][j];
            }
        }
        while(cin>>n)
        {
            cout<<d[21][n]<<endl;
        }
    }

    但是我们可以分析得出这个代码的时间复杂度接近O(N^3).所以我们应该把这个问题加以改进:

    对于第i个数字而言,我们可以这样分析:如果我们取一次第i个数字得到d(i,j)那么可以知道这是从状态d(i,j-i^3)转化得到;当我们不取第i个数字得到d(i,j)那么可以知道这是从状态d(i-1,j)转化得到。那么我们便可以得到递推公式:d(i,j)=d(i-1,j)+d(i,j-i^3)(如果大家想说我们如果需要用多个i^3怎么办?是不是这个公式不在成立呢?仔细想想还是成立的,因为我们如果再往下递推一层或者多层我们便可以使用多次i^3,那么我们便可以把代码写成如下形式:时间复杂度仅仅是O(n^2),而且我们可以用滚动数组节约存储空间。

    下面给出代码:

    #include<iostream>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    using namespace std;
    #define  MAXN 22*22*22
    long long dp[MAXN];
    int main()
    {
        int n;
        memset(dp,0,sizeof(dp));
        long long c[22];
        for(int i=1;i<22;i++)
            c[i]=i*i*i;
        dp[0]=1;
        for(int i=1;i<22;i++)
            for(int j=c[i];j<MAXN;j++)
            dp[j]+=dp[j-c[i]];
        while(cin>>n)
        {
            cout<<dp[n]<<endl;
        }
    }

    在合理选取递推式和状态时往往可以节省很多时间,提高效率。

  • 相关阅读:
    详解Javascript匿名函数的使用 转载自IT EYE Blog
    漂亮、免费和响应式HTML5网站模板 转
    Truth, Equality and JavaScript
    Ember.js 示例
    UX Pin 一款在线界面设计网站
    关于工资的三个秘密
    Semantic Versioning 如何进行版本管理
    CSSS CSS幻灯片
    oracle 导入数据报600错误
    Android 初步Android文件目录介绍
  • 原文地址:https://www.cnblogs.com/khbcsu/p/4252459.html
Copyright © 2011-2022 走看看