UVA - 1213
来源:互联网 发布:天刀天香捏脸数据图 编辑:程序博客网 时间:2024/05/20 20:01
分析:
以d[ i ][ j ] 表示数i分解为j个素数的所有方法; 第一个想到的状态转移方程 d[ i ][ j ] += d[ i -k ][ j-1 ] (k为比i小的素数),但改状态转移方程并不正确,如d[ 7 ][ 3 ]转移至d[ 5 ] [ 2 ];
5 可分解为 3+2 与刚才的2重复,换句话数d[ i ][ j ] 只依赖 d[ i -k ][ j-1 ] 中由j-1个素数组成并且所有素数都与k不同的那一部分;
这样可以考虑正向枚举所有1120内的素数,那么d[ i ] [ j ] 转移时剪掉当前素数k之后,状态d[ i -k ][ j-1 ]此时肯定只包含由比k小的素数组成的结;
#include <map>#include <vector>#include <cstdio>#include <cmath>#include <cstring>#include <iostream>#include <algorithm>#define INF 10000000using namespace std;typedef long long LL;const int maxn = 1120;vector<int> primes;int vis[maxn+10];void init_primes_table(){memset(vis,0,sizeof(vis));int m=sqrt(maxn+0.5);for(int i=2;i<=m;i++)if(!vis[i]) for(int j=i*i;j<=maxn;j+=i) vis[j]=1;for(int j=2;j<=maxn;j++)if(!vis[j]) primes.push_back(j);}int d[maxn+10][15];int main(){ init_primes_table(); memset(d,0,sizeof(d)); d[0][0]=1; int lim=primes.size(); for(int i=0;i<lim;i++){ for(int j=14;j>=1;j--){ for(int k=maxn;k>=primes[i];k--){ d[k][j]+=d[k-primes[i]][j-1]; } } } int n,m; while(scanf("%d %d",&n,&m)==2){ if(!n&&!m) break; printf("%d\n",d[n][m]); } return 0;}
0 0
- UVA - 1213
- UVa 1213
- uva
- UVA
- UVA
- UVA
- uva
- UVA
- UVA
- UVA
- UVA
- UVA
- UVA
- UVA
- UVA
- UVA
- UVA
- UVA
- 简单逆波兰计算器
- 黑马程序员--“云计算”逆天!月薪14000大神的经验爆料,不看后悔!
- Redis for Windows 安装使用教程
- 题目32:1-N整数中“1”出现的个数
- 可以实现复合控件单选的radioButton
- UVA - 1213
- 把每天做的题目存起来,虽然刚刚开始学,重在积累!加油!
- LDA主题模型简介
- 从零开始学android<ImageSwitcher图片切换组件.二十六.>
- Devexpress Gantt 应用
- 黑马程序员--一个为宝宝而努力的女程序员经历!!!!!!
- 花1K内存实现高效I/O的RandomAccessFile类
- facebook comments plugins 介绍
- C/C++ 定义并赋值二维数组