uva11375火柴递推之多状态转移递推
发布日期:2021-10-08 15:48:50 浏览次数:15 分类:技术文章

本文共 5727 字,大约阅读时间需要 19 分钟。

 

分析:把”已经使用过的火柴数i”看成状态,可以得到一个图。从前往后每添加一个数字x,就从状态i转移到i+c[x],其中c[x]代表数字x需要的火柴数。当i=0的时候不允许

使用数字0(最后当n>=6时,给答案单独加上1,代表整数0)。

令d(i)为从结点0到结点i的路径条数,则答案f(n)=d(1)+d(2)+d(3)+...+d(n)(因为火柴不必用完,所以使用的火柴的数目可能是1,2,3,...,n)。

程序实现时,我们可以按照从小到大的顺序用d(i)更新所有的d(i+c[j])(j取遍数字0~9),

这道题思路难度是状态转移,而编码难度在大数加法,好久没写大数加法,又有些生疏了,贴上代码:

#include
#include
#include
#include
#include
using namespace std;#define LL long longconst int MAXN=505;const int N=2005;struct bign{int len,num[MAXN];bign (){ len=0; memset(num,0,sizeof(num));}bign (int number){ *this=number;}void DelZero(){ while(len&&num[len-1]==0) { len--; } if(len==0) num[len++]=0;}void put(){ for(int i=len-1;i>=0;i--) cout<
>n) { dp[n].put(); cout<
下面贴上大数的其他运算:

#include 
#include
#include
using namespace std;const int MAXN = 505;struct bign { int len, num[MAXN]; bign () { len = 0; memset(num, 0, sizeof(num)); } bign (int number) {*this = number;} bign (const char* number) {*this = number;} void DelZero (); void Put (); void operator = (int number); void operator = (char* number); bool operator < (const bign& b) const; bool operator > (const bign& b) const { return b < *this; } bool operator <= (const bign& b) const { return !(b < *this); } bool operator >= (const bign& b) const { return !(*this < b); } bool operator != (const bign& b) const { return b < *this || *this < b;} bool operator == (const bign& b) const { return !(b != *this); } void operator ++ (); void operator -- (); bign operator + (const int& b); bign operator + (const bign& b); bign operator - (const int& b); bign operator - (const bign& b); bign operator * (const int& b); bign operator * (const bign& b); bign operator / (const int& b); //bign operator / (const bign& b); int operator % (const int& b);};/*Code*/const int N = 2005;const int c[20] = {6, 2, 5, 5, 4, 5, 6, 3, 7, 6};bign dp[N];int main () { dp[0] = 1; dp[1] = 0; for (int i = 0; i <= 2000; i++) { for (int j = 0; j < 10; j++) { if (i == 0 && j == 0) continue; if (i + c[j] <= 2000) dp[i+c[j]] = dp[i+c[j]] + dp[i]; } } dp[6] = dp[6] + 1; for (int i = 2; i <= 2000; i++) dp[i] = dp[i] + dp[i-1]; int n; while (scanf("%d", &n) == 1 && n > 0) { dp[n].Put(); printf("\n"); } return 0;}void bign::DelZero () { while (len && num[len-1] == 0) len--; if (len == 0) { num[len++] = 0; }}void bign::Put () { for (int i = len-1; i >= 0; i--) printf("%d", num[i]);}void bign::operator = (char* number) { len = strlen (number); for (int i = 0; i < len; i++) num[i] = number[len-i-1] - '0'; DelZero ();}void bign::operator = (int number) { len = 0; while (number) { num[len++] = number%10; number /= 10; } DelZero ();}bool bign::operator < (const bign& b) const { if (len != b.len) return len < b.len; for (int i = len-1; i >= 0; i--) if (num[i] != b.num[i]) return num[i] < b.num[i]; return false;}void bign::operator ++ () { int s = 1; for (int i = 0; i < len; i++) { s = s + num[i]; num[i] = s % 10; s /= 10; if (!s) break; } while (s) { num[len++] = s%10; s /= 10; }}void bign::operator -- () { if (num[0] == 0 && len == 1) return; int s = -1; for (int i = 0; i < len; i++) { s = s + num[i]; num[i] = (s + 10) % 10; if (s >= 0) break; } DelZero ();}bign bign::operator + (const int& b) { bign a = b; return *this + a;}bign bign::operator + (const bign& b) { int bignSum = 0; bign ans; for (int i = 0; i < len || i < b.len; i++) { if (i < len) bignSum += num[i]; if (i < b.len) bignSum += b.num[i]; ans.num[ans.len++] = bignSum % 10; bignSum /= 10; } while (bignSum) { ans.num[ans.len++] = bignSum % 10; bignSum /= 10; } return ans;}bign bign::operator - (const int& b) { bign a = b; return *this - a;}bign bign::operator - (const bign& b) { int bignSub = 0; bign ans; for (int i = 0; i < len || i < b.len; i++) { bignSub += num[i]; bignSub -= b.num[i]; ans.num[ans.len++] = (bignSub + 10) % 10; if (bignSub < 0) bignSub = -1; } ans.DelZero (); return ans;}bign bign::operator * (const int& b) { int bignSum = 0; bign ans; ans.len = len; for (int i = 0; i < len; i++) { bignSum += num[i] * b; ans.num[i] = bignSum % 10; bignSum /= 10; } while (bignSum) { ans.num[ans.len++] = bignSum % 10; bignSum /= 10; } return ans;}bign bign::operator * (const bign& b) { bign ans; ans.len = 0; for (int i = 0; i < len; i++){ int bignSum = 0; for (int j = 0; j < b.len; j++){ bignSum += num[i] * b.num[j] + ans.num[i+j]; ans.num[i+j] = bignSum % 10; bignSum /= 10; } ans.len = i + b.len; while (bignSum){ ans.num[ans.len++] = bignSum % 10; bignSum /= 10; } } return ans;}bign bign::operator / (const int& b) { bign ans; int s = 0; for (int i = len-1; i >= 0; i--) { s = s * 10 + num[i]; ans.num[i] = s/b; s %= b; } ans.len = len; ans.DelZero (); return ans;}int bign::operator % (const int& b) { bign ans; int s = 0; for (int i = len-1; i >= 0; i--) { s = s * 10 + num[i]; ans.num[i] = s/b; s %= b; } return s;}

转载地址:https://blog.csdn.net/ONE_PIECE_HMH/article/details/45251177 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:uva11137递推和DP其实有些类似
下一篇:UVA11806容斥原理,位运算排列,递推组合数

发表评论

最新留言

表示我来过!
[***.240.166.169]2024年03月28日 09时17分13秒