URAL 1353
来源:互联网 发布:it heard 编辑:程序博客网 时间:2024/06/05 04:49
题目大意:求1-10^9中各个位上的数的和为S的数的个数。
Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u
数据规模:1<=S<=81。
理论基础:无(dp题的关键在于状态与状态转移方程,理论什么的都貌似没多少)。
题目分析:用dp[i][j]表示n位数的各个位数和为j的个数。状态转移方程:dp[i][j]=sum(dp[i-1][j-k],0<k<10&&k<j)。答案就是:ans=sum(dp[i][S],1<=i<=9)+(S==1)(10^9单独处理)
But,这道题,由于规模太小我没们不用dp,那用什么?枚举呗,枚举打表就可以了。我们可以观察到:S=99与S=0是相等的,S=98与S==1(不计10^9时)是相等的,S=97与S=2是相等的,这不是偶然,是因为1用8替换,2用7替换,...。这样的话我们就只需要枚举到S=44就可以了,然后打表。O(1)解决此问题。
至于dp的方法大家可以下去试一下。这里不再详细说明。
代码如下:
#include<iostream>#include<cstring>#include<string>#include<cstdlib>#include<cstdio>#include<cmath>#include<algorithm>#include<queue>#include<ctime>#include<vector>using namespace std;typedef double db;#define DBG 0#define maa (1<<31)#define mii ((1<<31)-1)#define ast(b) if(DBG && !(b)) { printf("%d!!|\n", __LINE__); while(1) getchar(); } //调试#define dout DBG && cout << __LINE__ << ">>| "#define pr(x) #x"=" << (x) << " | "#define mk(x) DBG && cout << __LINE__ << "**| "#x << endl#define pra(arr, a, b) if(DBG) {\ dout<<#arr"[] |" <<endl; \ for(int i=a,i_b=b;i<=i_b;i++) cout<<"["<<i<<"]="<<arr[i]<<" |"<<((i-(a)+1)%8?" ":"\n"); \ if((b-a+1)%8) puts("");\}template<class T> inline bool updateMin(T& a, T b) { return a>b? a=b, true: false; }template<class T> inline bool updateMax(T& a, T b) { return a<b? a=b, true: false; }typedef long long LL;typedef long unsigned int LU;typedef long long unsigned int LLU;int ans[82]={1,10,45,165,495,1287,3003,6435,12870,24310,43749,75501,125565,202005,315315,478731,708444,1023660,1446445,2001285,2714319,3612231,4720815,6063255,7658190,9517662,11645073,14033305,16663185,19502505,22505751,25614639,28759500,31861500,34835625,37594305,40051495,42126975,43750575,44865975,45433800,45433800,44865975,43750575,42126975,40051495,37594305,34835625,31861500,28759500,25614639,22505751,19502505,16663185,14033305,11645073,9517662,7658190,6063255,4720815,3612231,2714319,2001285,1446445,1023660,708444,478731,315315,202005,125565,75501,43749,24310,12870,6435,3003,1287,495,165,45,9,1},s;int main(){ if(DBG) { for(int i=2;i<=81;i++) { int cnt=0; for(int i_a=0;i_a<=9;i_a++) { if(i_a>i)break; for(int i_b=0;i_b<=9;i_b++) { if(i_a+i_b>i)break; for(int i_c=0;i_c<=9;i_c++) { if(i_a+i_b+i_c>i)break; for(int i_d=0;i_d<=9;i_d++) { if(i_a+i_b+i_c+i_d>i)break; for(int i_e=0;i_e<=9;i_e++) { if(i_a+i_b+i_c+i_d+i_e>i)break; for(int i_f=0;i_f<=9;i_f++) { if(i_a+i_b+i_c+i_d+i_e+i_f>i)break; for(int i_g=0;i_g<=9;i_g++) { if(i_a+i_b+i_c+i_d+i_e+i_f+i_g>i)break; for(int i_h=0;i_h<=9;i_h++) { if(i_a+i_b+i_c+i_d+i_e+i_f+i_g+i_h>i)break; for(int i_i=0;i_i<=9;i_i++) { if(i_a+i_b+i_c+i_d+i_e+i_f+i_g+i_h+i_i>i)break; if(i_a+i_b+i_c+i_d+i_e+i_f+i_g+i_h+i_i==i)cnt++; } } } } } } } } } printf(",%d",cnt); } } else { while(~scanf("%d",&s)) { printf("%d\n",ans[s]); } }return 0;}
其中DBG在以前的博文里已经解释过了,打表时把DBG改为1,打好表后,提交代码时改为0即可。
by:Jsun_moon http://blog.csdn.net/Jsun_moon
- Ural 1353
- URAL 1353
- URAL
- 【ural】
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- URAL
- windows 窗口关系
- GitHub Android 最火开源项目Top20
- 【原创】从零开始——Android 4.0 实现recovery模式,出厂设置功能
- MongoDB初体验:win7下载安装
- POJ_1006_Biorhythms(中国剩余定理)
- URAL 1353
- SQL 函数
- [小说]魔王冢(40)谈判(二)
- 多重继承
- ios 修改应用名称
- spring_hibernate.xml
- 在eclipse中复制项目的问题
- 照这样计算。。。
- Command Pattern