Problem E: Eigensequence
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 by aj - aj-1.
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 has many data lines, followed by a terminating line. Each line has two integers, a1 and an. If a1 < an, 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.
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
Output for sample input
0 3 3 5 7 1 2 8 12
Don Reble
思路:简单的dp,用dp[i]表示以a序列以i为结尾的符合要求的数列有多少种。转移的时候dp[i] += dp[k] 其中(i,k]中只有一个数是能被(k-i)整除的。
代码:
#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
#include <string>
#include <queue>
#include <cassert>
using namespace std;
#define debug(x) cout << #x << " = " << x << endl;
#define rep(i,a,b) for(int i=(a);i<(b);++i)
#define rrep(i,b,a) for(int i = (b); i >= (a); --i)
#define clr(a,x) memset(a,(x),sizeof(a))
#define LL long long
#define eps 1e-9
#define mt make_tuple
const int maxn = 50;
LL dp[maxn];
inline int value(int l,int r)
{
int d = (r - l);
if (r % d) return 0;
int x = l / d * d;
if ((r - l) / d > 1) return 0;
return 1;
}
void solve(int l,int r)
{
printf("%d %d ",l,r);
clr(dp,0);
dp[l] = 1;
rep(i,l+1,r+1) {
rep(k,l,i)
dp[i] += dp[k] * value(k,i);
}
printf("%lld\n",dp[r]);
}
int main()
{
int l,r;
while (scanf("%d%d",&l,&r)==2) {
if (l >= r) break;
solve(l,r);
}
return 0;
}
//0 3 : 1
//0 2 3 : 1
//0 1 2 3 : 1