UVA 11133 - Eigensequence DP

Given an increasing sequence of integers a1, a2, a3, . . . , ak, the E-transform produces a sequence of the
same length, b1, b2, b3, . . . , bk such that
• b1 = a1
• for j > 1, bj is the only integer aj−1 < bj ≤ aj, which is divisible byaj − aj−1.
For example, from S = 0,1,4,9,16,25,36,49 one gets E(S) = 0,1,3,5,14,18,33,39.
A sequence S such that E(S) = S is called an eigensequence.
For instance, S = 2,3,4,6,8,12,16,18,20 is an eigensequence.
Given integers a1 and an, how many eigensequences (of any length) start with a1 and end with an?
Input
Input has many data lines, followed by a terminating line. Each line has two integers, a1 and an. If
a1 < n, it’s a data line. Otherwise it’s a terminating line that should not be processed. On each line,
0 ≤ a1 ≤ an ≤ 44. This guarantees that each output fits into 32 bit integer.
Output
For each data line, print a line with a1, an, and x, where x is the number of eigensequences (of any
length) that start with a1 and end with an.
Sample Input
0 3
5 7
2 8
0 0
Sample Output
0 3 3
5 7 1
2 8 12

 

题意:给你一个递增序列的第一位a1,最后一位an,求有多少个序列满足:以a1为首,an为尾

1、B(1) = A(1)

2、后面每项满足,A(j-1) < B(j) ≤ A(j), 且bj能整除A(j) - A(j-1)。

题解:看题目由于给的a1,an都很小我们设定dp[i][j]以第i位以结尾的方案数,

     那么  对于满足上述条件就能转移

//meek
#include<bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include<map>
#include<queue>
using namespace std ;
typedef long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define pb push_back
#define fi first
#define se second
#define MP make_pair

const int N=50;
const ll INF = 1ll<<61;
const int inf = 1000000007;
const int MOD= 1000000007;

ll dp[N][N],vis[N][N];
int a1,an;
ll dfs(int now,int sum) {
  if(vis[now][sum]) return dp[now][sum];
  vis[now][sum] = 1;
  ll& ret = dp[now][sum];
  ret = 0;
  if(sum == an) return ret = 1;
  for(int i = sum+1; i <= an; i++) {
    if(i%(i-sum)) continue;
    ret += dfs(now+1,i);
  }
    return ret;
}
int main() {
   while(~scanf("%d%d",&a1,&an)) {
    if(a1 == 0 && an == 0) break;
    mem(vis);
    printf("%d %d %lld\n",a1,an,dfs(a1,a1));
   }
    return 0;
}
代码

 

posted @ 2016-01-03 17:05  meekyan  阅读(267)  评论(0编辑  收藏  举报