题目:
奖券数目
有些人很迷信数字,比如带“4”的数字,认为和“死”谐音,就觉得不吉利。
虽然这些说法纯属无稽之谈,但有时还要迎合大众的需求。某抽奖活动的奖券号码是5位数(10000-99999),要求其中不要出现带“4”的号码,主办单位请你计算一下,如果任何两张奖券不重号,最多可发出奖券多少张。
请提交该数字(一个整数),不要写任何多余的内容或说明性文字。
代码:
#include<stdio.h>
#include<string.h>
using namespace std;
const int N = 10;
int n, m;
int bits[N];
int dp[N][3];
void init()
{
dp[0][0] = 1; // len is 0 and luck is 1, becauses the dp[1][1] will equal it.
dp[0][1] = dp[0][2] = 0;
for(int i=1; i<=N-1; i++)
//repf(i, 1, N - 1)
{
dp[i][0] = dp[i - 1][0] * 9 ; // i-1_luck without 4
//- dp[i - 1][1]; // and without 62
dp[i][1] = dp[i - 1][0]; // equal to i-1_luck_2 + '6'
dp[i][2] = dp[i - 1][2] * 10 // unluck is always unluck
+ dp[i - 1][0] ; // i-1_luck + '4'
//+ dp[i - 1][1]; // i-1_luck_2 + '6'
}
}
int solve(int num)
{
int len = 0, rec = num, ans, flag;
int uu=1;
// get bits array
while (num)
{
bits[++len] = num % 10;
num /= 10;
}
bits[len + 1] = 0;
ans = 0; // the unluck num
flag = 0; // if appear unluck
//printf("%d\n",len);
//printf("%d %d %d\n",bits[3],bits[2],bits[1]);
for(int i=len; i>=1; i--)
//repd (i, len, 1)
{
//printf("%d ",bits[i]);
ans =ans + dp[i - 1][2] * bits[i]; // unluck is always unluck
if (flag) // if unluck appeared
{
ans += dp[i - 1][0] * bits[i]; // all luck become unluck
}
else
{
if (bits[i] > 4)
{
ans += dp[i - 1][0]; // i-1_luck + '4'
}
}
if (bits[i] == 4 )
{
flag = 1;
}
//printf("%d ",ans);
}
// printf("%d\n",rec-ans);
return rec - ans;
}
int main()
{
init();
printf("%d\n",solve(100 + 1) - solve(1));
}
代码是 不要62 改的数位dp的原理还是不太懂,再看看。