AOJ1269 Sum of Different Primes
問題リンク Sum of Different Primes
- 概要
整数NをK個の異なる素数の和で表す方法は何通りあるか答えよ。3+5と5+3などは重複して数えてはならない。
N <= 1120
K <= 14
- 解法
メモ化再帰で解くことができます。
dp[i][j][k]: 整数iをj番目以降の素数をk個使って表す方法の個数
という部分問題に落とせます。1120以下の素数の数は187個なので、1120*187*14 = 3*10^6程度の計算量になります。
- ソース
import java.util.Arrays; import java.util.Scanner; //Sum of Different Primes public class AOJ1269 { int N = 1120, num; int[] p; int[][][] dp; int get(int x, int index, int rest){ if(rest==0){ if(x==0)return dp[x][index][rest] = 1; else return dp[x][index][rest] = 0; } if(dp[x][index][rest]!=-1)return dp[x][index][rest]; int res = 0; for(int i=index;i<num;i++){ if(x<p[i])break; res += get(x-p[i], i+1, rest-1); } return dp[x][index][rest] = res; } void run(){ num = 0; p = new int[187]; boolean[] prime = new boolean[N+1]; Arrays.fill(prime, true); prime[0]=prime[1]=false; for(int i=2;i<=N;i++)if(prime[i]){ p[num++] = i; for(int j=i+i;j<=N;j+=i)prime[j]=false; } dp = new int[N+1][num+1][15]; for(int i=0;i<=N;i++)for(int j=0;j<=num;j++)for(int k=0;k<=14;k++)dp[i][j][k]=-1; Scanner sc = new Scanner(System.in); for(;;){ int n = sc.nextInt(), k = sc.nextInt(); if((n|k)==0)break; System.out.println(get(n, 0, k)); } } public static void main(String[] args) { new AOJ1269().run(); } }