递推关系的运用加简单DP【UVA11137Ingenuous Cubrency】-------2015年1月27日
2015-01-27 11:51
453 查看
一:题意描述
本题就是求立方数之和。输入正整数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的常数)所以我们可以写出如下代码:
但是我们可以分析得出这个代码的时间复杂度接近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),而且我们可以用滚动数组节约存储空间。
下面给出代码:
在合理选取递推式和状态时往往可以节省很多时间,提高效率。
本题就是求立方数之和。输入正整数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] <<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 <<endl; } }
在合理选取递推式和状态时往往可以节省很多时间,提高效率。
相关文章推荐
- uva--11137Ingenuous Cubrency ---dp
- uva1638(递推关系,dp)
- UVa 11137 - Ingenuous Cubrency (递推 DP 多重背包 )
- UVA 11137 Ingenuous Cubrency 类似硬币问题的简单dp
- uva 11375 Matches 递推关系||DP||高精度
- UVA111 History Grading 简单的DP
- POJ 2441 Arrange the Bulls 状态压缩递推简单题 (状态压缩DP)
- UVa 10201 Adventures in Moving(简单DP)
- UVa 10453 Make Palindrome(简单DP)
- UVa 10404 Bachet's Game(简单DP)
- UVA 10739 String to Palindrome 转换回文 dp递推
- uva116 - Unidirectional TSP(简单DP)
- UVa 437 The Tower of Babylon(简单DP)
- UVA10564-----Paths through the Hourglass-----简单的计数DP
- UVA 674 —— 简单DP
- 简单递推系列 uva习题
- uva 11584 - Partitioning by Palindromes(简单dp)
- UVa 11137 Ingenuous Cubrency(简单DP)
- UVa 562 Dividing coins(简单DP)
- UVa 607 Scheduling Lectures(简单DP)