http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=20079
题意:
给你一个电话号码,根据这个号码生成一个新的号码。生成的规则就是 新号码的第一个数任意选(0-9), 然后之后的每一个新号码都按照以下规则生成:
第i个新号码 = (第 i-1个新号码 +第i个老号码 的和)/2 , 这里如果乘除,则新号码i唯一,否则新号码i可以向上或向下取整;
求总共能生成多少种号码
q=第i+1位的老号码; j为第i位上的新号码<span style="white-space:pre"> </span>if ((q+j)%2==0)
dp[i][j]=dp[i+1][(q+j)/2];
else
dp[i][j]=dp[i+1][(q+j)/2]+dp[i+1][(q+j+1)/2];如果发现老号码本身能得到 自己,那么种类数要减一 (求得是 生成的 新的号码数)
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
using namespace std;
__int64 tm[55];
__int64 dp[55][15];
char s[105];
__int64 test[55];
int main()
{
__int64 i,j;
scanf("%s",s);
__int64 n=strlen(s);
for (i=0;i<n;i++)
tm[i+1]=s[i]-'0';
for (j=0;j<=9;j++)
dp[n][j]=1;
for (i=n-1;i>=1;i--)
{
for (j=0;j<=9;j++)
{
__int64 q=tm[i+1];
if ((q+j)%2==0)
dp[i][j]=dp[i+1][(q+j)/2];
else
dp[i][j]=dp[i+1][(q+j)/2]+dp[i+1][(q+j+1)/2];
}
}
__int64 flag=1;
for (i=1;i<=n;i++)
test[i]=tm[i];
for (i=2;i<=n;i++)
{
if ((test[i]==(tm[i]+test[i-1])/2)
||(test[i]==(tm[i]+test[i-1]+1)/2) )
continue;
else
{
flag=0; //自己不在里面
break;
}
}
__int64 ans=0;
for (i=0;i<=9;i++)
{
ans+=dp[1][i];
}
printf("%I64d\n",ans-flag);
return 0;
}
本文介绍了一种基于递归思想的电话号码转换算法,该算法能够根据特定规则生成新的电话号码组合,并通过动态规划方法计算所有可能的新号码总数,同时考虑了特殊情况下的数量修正。

511

被折叠的 条评论
为什么被折叠?



