明七暗七 [二分+数位DP]

明七暗七 

思路:二分+数位DP

#include 

using namespace std;
typedef long long ll;
ll dp[50][10][3];
int bit[50];
ll dfs(int pos,int mod,int have,bool lead,bool limit){
    if(pos==-1) return (mod==0||have==1);
    if(!limit && !lead && dp[pos][mod][have]!=-1)   return dp[pos][mod][have];
    int up=limit ? bit[pos] : 9;
    ll ans=0;
    for(int i=0;i<=up;i++){
        ll tempmode=(mod*10+i)%7; //模拟除法过程,13的倍数
        ll temphave=have;
        if(i==7)   temphave=1;
        ans+=dfs(pos-1,tempmode,temphave,i==0&&lead,limit&&bit[pos]==i);
    }
    if(!limit && !lead) dp[pos][mod][have]=ans;
    return ans;
}
ll solve(ll t){
//    memset(dp,-1,sizeof dp);
    int pos=0;
    while(t){
        bit[pos++]=t%10;
        t/=10;
    }
    return dfs(pos-1,0,0,true,true);
    ///最高位,前一位,前导零,是否限制
}
int main(void){
    ll m,n;
    cin >> m>> n;
    ll l=m+1,r=1e18;memset(dp,-1,sizeof dp);
    ll cnt=solve(m);
    ll ans;

    while(l<=r){
        ll mid=l+r>>1;
        ll tans=solve(mid);
        if(cnt+n>tans) l=mid+1;
        else    ans=mid,r=mid-1;
    }
    cout << ans << endl;


    return 0 ;
}

 

你可能感兴趣的:(动态规划之基础DP,二分搜索)