3539: [Usaco2014 Open]Odometer
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 33 Solved: 24
[ Submit][ Status][ Discuss]
Description
Farmer John's cows are on a road trip! The odometer on their car displays an integer mileage value, starting at X (100 <= X <= 10^18) miles at the beginning of their trip and ending at Y (X <= Y <= 10^18) miles at the end of their trip. Whenever the odometer displays an 'interesting' number (including at the start and end of the trip) the cows will moo. A number is 'interesting' if when you look at all its digits except for leading zeros, at least half of these should be the same. For example, the numbers 3223 and 110 are interesting, while the numbers 97791 and 123 are not. Help FJ count how many times the cows will moo during the trip.
Input
* Line 1: The first line will contain two integers, X and Y, separated by a space.
Output
* Line 1: A single integer containing how many times the cows will moo during the trip.
Sample Input
INPUT DETAILS: The trip starts with the odometer at 110 and ends at 133.
Sample Output
OUTPUT DETAILS: The cows moo when the odometer reads 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 121, 122, 131, and 133.
HINT
Source
麻烦的DP题,不会做,抄代码。
dp[i][und][k][j],i表示位置,und表示i之前的位置是否小于上界,k为计数器(为了避免出现负数从25开始),j表示是否前面都为前导零。需要注意的是形如2233、454545这种只有两个数字且次数一样的会被计算两次,所以最后要减去。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define F(i,j,n) for(int i=j;i<=n;i++)
#define D(i,j,n) for(int i=j;i>=n;i--)
#define LL long long
#define MAXN 50
using namespace std;
string a,b;
LL dp[MAXN][2][MAXN][2];
LL getdp(string s,int l,int p1,int p2)
{
memset(dp,0,sizeof(dp));
dp[0][false][25][true]=1;
F(i,0,l-1) F(und,0,1)
{
F(k,0,MAXN-1)
{
F(j,0,1)
{
LL cur=dp[i][und][k][j];
F(nxt,0,9)
{
if (p2!=-1&&(nxt!=0||j==false)&&nxt!=p1&&nxt!=p2) continue;
if (und==0&&nxt>s[i]-'0') continue;
bool nj=j;
nj&=!nxt;
int nk=k;
if (!nj)
{
if (p2!=-1)
{
if (nxt==p1) nk--;
else if (nxt==p2) nk++;
}
if (p2==-1)
{
if (nxt==p1) nk--;
else nk++;
}
}
int nund=und;
nund|=(nxt<s[i]-'0');
dp[i+1][nund][nk][nj]+=cur;
}
}
}
}
LL ret=0;
if (p2!=-1)
{
F(i,0,1) ret+=dp[l][i][25][0];
return ret;
}
F(i,0,1) F(k,0,25) ret+=dp[l][i][k][0];
return ret;
}
LL f(string s)
{
int l=s.size();
LL ret=0,val;
F(targ1,0,9)
{
val=getdp(s,l,targ1,-1);
ret+=val;
}
F(targ1,0,9) F(targ2,targ1+1,9)
{
val=getdp(s,l,targ1,targ2);
ret-=val;
}
return ret;
}
int main()
{
cin>>a>>b;
D(i,a.size()-1,0)
{
int c=a[i]-'0';
if (c>0)
{
a[i]--;
break;
}
else a[i]='9';
}
LL ans1=f(a),ans2=f(b);
printf("%lld\n",ans2-ans1);
return 0;
}