hdoj 1028

来源:互联网 发布:数据库培训哪家好 编辑:程序博客网 时间:2024/05/22 04:38

题目大意:求出将给定数字分成若干正整数的不同方法个数

题目分析:该题可等价转化为硬币转化问题:有各种正整数面值的硬币,求出给定钱数的不同组合方式的个数,定义dp(x,y)为能组成x元的,且最大面值为coin[y]的不同组合方式。状态转移方程为:dp(x,y) = dp(x-coin[y],y)+dp(x,y-1);

则答案只需要从最大的y开始往前扫,第一个不为零的dp(x,y)即为答案。

代码如下:

#include <iostream>#include <stdio.h>#include <fstream>#include <iomanip>#include <cmath>#include <string>#include <string.h>#include <sstream>#include <cctype>#include <climits>#include <set>#include <map>#include <queue>#include <vector>#include <iterator>#include <algorithm>#include <stack>#include <functional>/*int类型最大值INT_MAX,short最大值为SHORT_MAXlong long最大值为LONG_LONG_MAX*///cout << "OK" << endl;#define _clr(x) memset(x,0,sizeof(x))using namespace std;const int INF = INT_MAX;const double eps = 1e-8;const double EULER = 0.577215664901532860;const double PI = 3.1415926535897932384626;const double E = 2.71828182845904523536028;typedef long long LL;//const int coin[5] = {1,5,10,25,50};int res[150][150] = {0};int dp(int x,int y){if(res[x][y]) return res[x][y];int ans = 0;for(int j = y;j>=1;j--){if(x<j) continue;ans+=dp(x-j,j);}return res[x][y] = ans;}int main(){    //freopen("sample.in", "r", stdin);//freopen("sample.out", "w", stdout);for(int j = 120;j>=0;j--) res[0][j] = 1;for(int i = 1;i<=120;i++)for(int j = 120;j>=1;j--){if(i<j) continue;res[i][j] = dp(i,j);}int n;while(cin >> n)for(int j = 120;j>=1;j--)if(res[n][j]){cout << res[n][j] << endl;break;}    //fclose(stdin);    //fclose(stdout);     return 0;}

0 0
原创粉丝点击