UVA 11133 - Eigensequence

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>1bj is the only integer aj-1 < bj ≤ aj, which is divisible by aj - 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 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 a1an, 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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值