不要62和帶4的值
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
int data[20];
ll dp[25][2];
ll dfs(int pos, int h, int sta, bool limit) //limit爲臨界判斷,pos爲當前位數(從高到低)其他值根據題意設置
{
if(pos == 0) return 1;
if(!limit && dp[pos][sta]!=-1) return dp[pos][sta]; //一般不變
int up = limit ? data[pos] : 9; //當前位最大值
ll ans = 0;
for(int i = 0; i <= up; i++)
{
if(i==4) continue; //不滿足的條件
if(h==6&&i==2) continue;
ans += dfs(pos - 1, i, i==6, i == data[pos] && limit); //遞歸
}
if(!limit) dp[pos][sta] = ans; //記憶化
return ans;
}
//將每一位存起來
ll solve(ll n)
{
int pos = 0;
while(n)
{
data[++pos] = n % 10;
n /= 10;
}
return dfs(pos , 0, 1, true);
}
int main()
{
ll a, b;
int cnt = 0;
memset(dp, -1, sizeof(dp));
while(~scanf("%lld %lld", &a, &b)&&(a||b))
{
printf("%lld\n", solve(b) - solve(a - 1));
}
return 0;
}
只要帶49的數
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
int data[20];
ll dp[25][2][2];
ll dfs(int pos, int h, int sta, bool limit)
{
if(pos == 0)
return h;
if(!limit && dp[pos][h][sta]!=-1)
return dp[pos][h][sta];
int up = limit ? data[pos] : 9;
ll ans = 0;
for(int i = 0; i <= up; i++)
{
if(sta&&i==9)
ans += dfs(pos-1,1,0,i==data[pos]&&limit); //符合條件
else
ans+=dfs(pos-1,h,i==4,i==data[pos]&&limit); //不符合條件
}
if(!limit)
dp[pos][h][sta] = ans;
return ans;
}
ll solve(ll n)
{
int pos = 0;
while(n)
{
data[++pos] = n % 10;
n /= 10;
}
return dfs(pos, 0, 0, true);
}
int main()
{
ll a, n;
scanf("%lld",&n);
int cnt = 0;
memset(dp, -1, sizeof(dp));
while(n--)
{
scanf("%lld", &a);
printf("%lld\n", solve(a));
}
return 0;
}
能被13整除並帶13的數字
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
int data[20];
ll dp[25][2][20][10];
ll dfs(int pos, int h,int k, int sta, bool limit) k爲當前數取餘13的值,又a%mod+b%mod=(a+b)%mod可以驗證方法正確
{
if(pos == 0)
return h==1&&k==0;
if(!limit && dp[pos][h][k][sta]!=-1)
return dp[pos][h][k][sta];
int up = limit ? data[pos] : 9;
ll ans = 0;
for(int i = 0; i <= up; i++)
{
if(sta==1&&i==3)
ans+= dfs(pos-1,1,(k*10+i)%13,i,i==data[pos]&&limit); //判斷是否含13
else
ans+=dfs(pos-1,h,(k*10+i)%13,i,i==data[pos]&&limit);
}
if(!limit)
dp[pos][h][k][sta] = ans;
return ans;
}
ll solve(ll n)
{
int pos = 0;
while(n)
{
data[++pos] = n % 10;
n /= 10;
}
return dfs(pos, 0, 0,0, true);
}
int main()
{
ll a;
memset(dp, -1, sizeof(dp));
while(~scanf("%lld", &a))
printf("%lld\n", solve(a));
return 0;
}
HDU - 3709 找到平衡支點, 例如4139中以3爲支點4*2 + 1*1 = 9 and 9*1 = 9,則該數爲我們要找的數。
這題多出來的一步是找平衡支點,遍歷查找即可。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
int data[20];
ll dp[25][25][2100];
ll maxx;
ll dfs(int pos, int o,int sta, bool limit)
{
if(pos == 0)
return sta==0;
if(sta<0)
return 0;
if(!limit && dp[pos][o][sta]!=-1)
return dp[pos][o][sta];
int up = limit ? data[pos] : 9;
ll ans = 0;
for(int i = 0; i <= up; i++)
ans+=dfs(pos-1,o,sta+i*(pos-o),i==data[pos]&&limit);
if(!limit)
dp[pos][o][sta] = ans;
return ans;
}
ll solve(ll n)
{
int pos = 0;
ll ans=0;
while(n)
{
data[++pos] = n % 10;
n /= 10;
}
for(int i=1; i<=pos; i++)
ans+=dfs(pos,i,0, 1);
return ans+1-pos; //0000計算了4次,減去pos-1次
}
int main()
{
ll a,n,b;
memset(dp, -1, sizeof(dp));
scanf("%lld",&n);
while(n--)
{
scanf("%lld %lld", &a,&b);
printf("%lld\n",solve(b)-solve(a-1));
}
return 0;
}