POJ_3181_记忆化搜索、高精度优化

来源:互联网 发布:黎巴嫩真主党 知乎 编辑:程序博客网 时间:2024/06/02 03:11

在床上打代码也是够爽


题意:

屌屌的约翰去买东西,他一共打算买N元钱的东西,他有无穷张1-K面值的钱,问他又多少中方法不找零支付N元钱。

(1 <= N <= 1000, 1 <= K <= 100)


果断是动态规划或者记忆化搜索,但是N,K太大,爆long long,高精度加法即可

但是十进制高精度TLE,采用高位进制,最终采用10^5进制,最大一组数据也可以瞬出。高位进制输出时注意会少0,要判断。


代码如下

#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<cstdlib>#include<ctime>using namespace std;#define mxn 1010#define mxk 110int n,k;struct bign{int a[10];int len;bign(){len=-1;}bign set(int in){len=0;while(in){a[len++]=in%100000;in/=100000;}return *this;}bign(int in){set(in);}void set(){len=-1;}bool ok(){return len!=-1;}bign operator + (const bign& in)const{bign ret;int pre=0;ret.len=max(in.len,len);for(int i=0;i<ret.len;++i){int tem=pre;if(i<len)tem+=a[i];if(i<in.len)tem+=in.a[i];pre=tem/100000;ret.a[i]=tem%100000;}if(pre)ret.a[ret.len++]=pre%100000;return ret;}void print(){printf("%d",a[len-1]);for(int i=len-2;i>=0;--i){if(a[i]/10000==0)printf("0");else if(a[i]/1000==0)printf("00");else if(a[i]/100==0)printf("000");else if(a[i]/10==0)printf("0000");printf("%d",a[i]);}}};bign dp[mxn][mxk];bign dfs(int now,int val){if(dp[now][val].ok())return dp[now][val];//cout<<"now "<<now<<" val "<<val<<endl;if(now==n)return dp[now][val].set(1);dp[now][val].set(0);if(val==k+1)return dp[now][val].set(0);for(int i=0;i*val+now<=n;++i)dp[now][val]=dp[now][val]+dfs(now+i*val,val+1);return dp[now][val];}int main(){scanf("%d%d",&n,&k);bign ans=dfs(0,1);ans.print();puts("");return 0;}


0 0