Evanyou Blog 彩带

CF44H Phone Number

题意翻译

给你一个电话号码,根据这个号码生成一个新的号码。生成的规则就是 新号码的第一个数任意选(0-9), 然后之后的每一个新号码都按照以下规则生成:

第i个新号码=(第i-1个新号码+第i个老号码的和)/2 

这里如果乘除,则新号码i唯一,否则新号码i可以向上或向下取整。
求总共能生成多少种号码

感谢@夜刀神十香ღ 提供的翻译

题目描述

Alas, finding one's true love is not easy. Masha has been unsuccessful in that yet. Her friend Dasha told Masha about a way to determine the phone number of one's Prince Charming through arithmancy.

The phone number is divined like that. First one needs to write down one's own phone numbers. For example, let's suppose that Masha's phone number is 1234512345 . After that one should write her favorite digit from 00 to 99 under the first digit of her number. That will be the first digit of the needed number. For example, Masha's favorite digit is 99 . The second digit is determined as a half sum of the second digit of Masha's number and the already written down first digit from her beloved one's number. In this case the arithmetic average equals to (2+9)/2=5.5(2+9)/2=5.5 . Masha can round the number up or down, depending on her wishes. For example, she chooses the digit 55 . Having written down the resulting digit under the second digit of her number, Masha moves to finding the third digit in the same way, i.e. finding the half sum the the third digit of her number and the second digit of the new number. The result is (5+3)/2=4(5+3)/2=4 . In this case the answer is unique. Thus, every ii -th digit is determined as an arithmetic average of the ii -th digit of Masha's number and the i-1i1 -th digit of her true love's number. If needed, the digit can be rounded up or down. For example, Masha can get:

1234512349544495444 Unfortunately, when Masha tried dialing the number, she got disappointed: as it turned out, the number was unavailable or outside the coverage area. But Masha won't give up. Perhaps, she rounded to a wrong digit or chose the first digit badly. That's why she keeps finding more and more new numbers and calling them. Count the number of numbers Masha calls. Masha calls all the possible numbers that can be found by the described means of arithmancy, except for, perhaps, her own one.

输入输出格式

输入格式:

 

The first line contains nonempty sequence consisting of digits from 00 to 99 — Masha's phone number. The sequence length does not exceed 5050 .

 

输出格式:

 

Output the single number — the number of phone numbers Masha will dial.

 

输入输出样例

输入样例#1: 
12345
输出样例#1: 
48
输入样例#2: 
09
输出样例#2: 
15

 

Solution:

  本题先给定了一段数字,那么新生成的在第i位的数推及第i+1位及以后的方案都是固定的,于是我们考虑记忆化搜索。

  定义状态$f[i][j]$表示当前在第i位且上一位的答案为j的方案数,则不难得到状态转移方程:$f[i][j]=f[i+1][\lfloor \frac{s[i]+j}{2}\rfloor]+f[i+1][\lceil \frac{s[i]+j}{2} \rceil]$,注意转移时若$s[i]+j$为偶数就不需要加第二个情况。

  那么答案为$\sum\limits_{i=0}^{i\leq 9}{f[2][i]}$,坑点是当$i\leq n$都满足$s[i]-s[i-1]\leq 1$时,会出现和原号码一模一样的情况,此时答案还需减1。

代码:

#include<bits/stdc++.h>
#define il inline
#define ll long long
#define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define Bor(i,a,b) for(int (i)=(b);(i)>=(a);(i)--)
using namespace std;
const int N=55;
ll n,ans,f[N][10];
char s[N];

ll dfs(int tot,int lst){
    if(tot>n) return 1;
    if(f[tot][lst]!=-1)return f[tot][lst];
    int p=(s[tot]^48)+lst;
    return f[tot][lst]=dfs(tot+1,p>>1)+(p&1?dfs(tot+1,p+1>>1):0);
}

int main(){
    cin>>s+1,n=strlen(s+1);
    if(n==1)puts("9"),exit(0);
    memset(f,-1,sizeof(f));
    For(i,0,9) ans+=dfs(2,i);
    For(i,2,n) if(abs(s[i]-s[i-1])>1)break; else if(i==n)ans--;
    cout<<ans;
    return 0;
}

 

posted @ 2018-08-16 16:22  five20  阅读(290)  评论(0编辑  收藏  举报
Live2D