POJ3181 dp递推关系小优化 高精度数模板 Java练习

来源:互联网 发布:拍孕肚用什么软件 编辑:程序博客网 时间:2024/04/28 10:42

题意 给你n和m,问你用1...m这些数,每种无限个,相互组合,形成求和为n的方案数。

思路 dp(i,j) 表示组成求和为i,且选用的这些数最小的要>j方案数。

   转移:dp(i,j) = dp(i,j+1) + dp(i-j,j)

   注意最后数会超long long 用高精度数。


C++:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <string>using namespace std;const int maxn = 1003;const int maxm = 102;int n,m;const int MAXSIZE = 100;struct BigInt{public:int a[MAXSIZE];int length;public:BigInt():length(0){memset(a,0,sizeof(a));}BigInt(string s);BigInt(int b);BigInt(const BigInt& c);BigInt operator=(int b);BigInt operator=(string s);};////////////////////////////////////////////////////////////////////////////////////////////////////////////////BigInt::BigInt(string s){memset(a,0,sizeof(a));*this = s;}BigInt::BigInt(int b){memset(a,0,sizeof(a));*this = b;}BigInt::BigInt(const BigInt& c){int i;memset(a,0,sizeof(a));length = c.length;memset(a,0,sizeof(a));for(i=0;i<length;i++){a[i] = c.a[i];}}BigInt BigInt::operator=(int b){memset(a,0,sizeof(a));if(b==0){a[0] = 0;length = 1;}if(b<0){b = -b;}for(length=0;b>0;length++){a[length] = b%10;b /= 10;}return *this;}BigInt BigInt::operator=(string s){int i;length = s.length();memset(a,0,sizeof(a));for(i=0;i<length;i++){a[length-i-1] = (int)(s[i] - '0');}return *this;}BigInt operator+(const BigInt& d,const BigInt& b){int i;int jinWei = 0;BigInt sum;int max_length = (d.length<b.length)?b.length:d.length;for(i=0;i<max_length;i++){jinWei = d.a[i]+b.a[i]+jinWei;sum.a[i] = jinWei%10;jinWei/=10;}sum.length = i;                //sum.length 易忘赋值 if(jinWei!=0) {sum.a[i] = jinWei; //加上最高位进位sum.length++; }return sum;}BigInt operator-(const BigInt& d,const BigInt& b)   //适宜d>b时 {int i,j;int tuiWei = 0;BigInt sum;int max_length = (d.length<b.length)?b.length:d.length;for(i=0;i<max_length;i++){tuiWei = d.a[i]-b.a[i]-tuiWei;if(tuiWei>=0){sum.a[i] = tuiWei;tuiWei = 0;}else{sum.a[i] = 10+tuiWei;tuiWei = 1;}}sum.length = i;                //sum.length 易忘赋值for(j=i-1;sum.a[j]==0&&j>0;j--)sum.length--;return sum;}BigInt operator*(const BigInt& d,const BigInt& b){int i,j,k;int jinWei=0;BigInt temp = 0;BigInt fuck = 0;if(b.a[0]==0&&b.length == 1||d.a[0]==0&&d.length == 1){return b;}for(i=0;i<b.length;i++)   //b作为乘数 {jinWei = 0;temp = 0; for(j=0;j<d.length;j++) //a*b[i] {jinWei = d.a[j]*b.a[i] + jinWei;temp.a[j] = jinWei%10;jinWei /= 10;}temp.length = j;if(jinWei!=0){temp.a[j] = jinWei; temp.length++;} if(i!=0){ for(k=temp.length-1;k>=0;k--)  //左移i位  { temp.a[k+i] = temp.a[k]; temp.a[k] = 0; } temp.length += i; }fuck = fuck+temp;}return fuck;}bool operator<(const BigInt& d,const BigInt& b){if(d.length<b.length)return true;if(d.length>b.length)return false;for(int i=b.length-1;i>=0;i--){if(d.a[i]>b.a[i])return false;if(d.a[i]<b.a[i])return true;}return false;}bool operator==(const BigInt& d,const BigInt& b){if(d.length!=b.length)return false;for(int i=b.length-1;i>=0;i--){if(d.a[i]!=b.a[i])return true;}return true;}bool operator!=(const BigInt& d,const BigInt& b){return !(d==b);}bool operator>(const BigInt& d,const BigInt& b){return !(d==b||d<b);}bool operator<=(const BigInt& d,const BigInt& b){return !(d>b);}bool operator>=(const BigInt& d,const BigInt& b){return !(d<b);}//////////////////////////////////////////////////////////////////////////////////////////char* toString(BigInt a){int i;static char s[MAXSIZE];for(i=a.length-1;i>=0;i--){s[a.length-i-1] = (char)(a.a[i]+'0');}s[a.length] =  '\0';return s;}BigInt dp[maxn][maxm];int main(){int i,j;while(scanf("%d%d",&n,&m) == 2){for(i=1;i<=m;i++){dp[0][i] = 1;}for(i=1;i<=n;i++){for(j=min(m,i);j>=1;j--){dp[i][j] = dp[i][j+1] + dp[i-j][j];}}char* tmp = toString(dp[n][1]);printf("%s\n",tmp);}return 0;}



Java

import java.util.*;import java.math.*;public class Main{static final int maxn = 1003;static final int maxm = 102;static BigInteger[][] dp = new  BigInteger[maxn][maxm];static Scanner cin = new Scanner(System.in);static public void main(String args[]){int n,m;while(cin.hasNextInt() == true){n = cin.nextInt();m = cin.nextInt();int i = 0,j = 0;for(i = 1;i<=m;i++)dp[0][i] = BigInteger.ONE;for(i=1;i<=n;i++){for(j=Math.min(i,m);j>=1;j--){if(dp[i][j+1] == null)dp[i][j+1] = BigInteger.ZERO;if(dp[i-j][j] == null)dp[i-j][j] = BigInteger.ZERO;dp[i][j] = BigInteger.ZERO;dp[i][j] = dp[i][j+1].add(dp[i-j][j]);}}System.out.println(dp[n][1].toString());}}}


0 0