以前刷过的数位dp

TOJ1688: Round Numbers 

Description

The cows, as you know, have no fingers or thumbs and thus are unable to play Scissors, Paper, Stone' (also known as 'Rock, Paper, Scissors', 'Ro, Sham, Bo', and a host of other names) in order to make arbitrary decisions such as who gets to be milked first. They can't even flip a coin because it's so hard to toss using hooves.

They have thus resorted to "round number" matching. The first cow picks an integer less than two billion. The second cow does the same. If the numbers are both "round numbers", the first cow wins,
otherwise the second cow wins.

A positive integer N is said to be a "round number" if the binary representation of N has as many or more zeroes than it has ones. For example, the integer 9, when written in binary form, is 1001. 1001 has two zeroes and two ones; thus, 9 is a round number. The integer 26 is 11010 in binary; since it has two zeroes and three ones, it is not a round number.

Obviously, it takes cows a while to convert numbers to binary, so the winner takes a while to determine. Bessie wants to cheat and thinks she can do that if she knows how many "round numbers" are in a given range.

Help her by writing a program that tells how many round numbers appear in the inclusive range given by the input (1 ≤ Start < Finish ≤ 2,000,000,000).

Input

Line 1: Two space-separated integers, respectively Start and Finish.

Output

Line 1: A single integer that is the count of round numbers in the inclusive range Start..Finish

Sample Input

Sample Output

Source

USACO November 2006

0的个数进行dp

 

#include<bits/stdc++.h>
using namespace std;
int dp[32][66],a[32],l,r;
int dfs(int pos,int st,int pre,int lim)
{
    if(pos<0)return st<=32;
    if(!lim&&!pre&&dp[pos][st]!=-1)return dp[pos][st];
    int mi=lim?a[pos]:1,ans=0;
    for(int i=0;i<=mi;i++)
        if(pre&&!i)ans+=dfs(pos-1,st,1,lim&&i==a[pos]);
        else ans+=dfs(pos-1,i?st+1:st-1,0,lim&&i==a[pos]);
    if(!lim&&!pre)dp[pos][st]=ans;
    return ans;
}
int la(int x)
{
    int tot=0;
    while(x)a[tot++]=x&1,x>>=1;
    return dfs(tot-1,32,1,1);
}
int main()
{
    memset(dp,-1,sizeof dp);
    scanf("%d%d",&l,&r);
    printf("%d\n",la(r)-la(l-1));
    return 0;
}

 

不要62

 HDU - 2089 

杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer)。 
杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍,更安全地服务大众。 
不吉利的数字为所有含有4或62的号码。例如: 
62315 73418 88914 
都属于不吉利号码。但是,61152虽然含有6和2,但不是62连号,所以不属于不吉利数字之列。 
你的任务是,对于每次给出的一个牌照区间号,推断出交管局今次又要实际上给多少辆新的士车上牌照了。 

Input输入的都是整数对n、m(0<n≤m<1000000),如果遇到都是0的整数对,则输入结束。 
Output对于每个整数对,输出一个不含有不吉利数字的统计个数,该数值占一行位置。 
Sample Input

1 100
0 0

Sample Output

80

很简单的数位dp

#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lson l,(l+r)/2,rt<<1
#define rson (l+r)/2+1,r,rt<<1|1
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define pb push_back
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define pll pair<long long,long long>
#define pii pair<int,int>
#define pq priority_queue
const int N=15,MD=1e9+7,INF=0x3f3f3f3f;
const ll LL_INF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-9,e=exp(1),PI=acos(-1.);
int c[N],dp[N][2];
int dfs(int pos,int st,int pre,int lim)
{
    if(pos<0)return 1;
    if(!lim&&dp[pos][st]!=-1)return dp[pos][st];
    int last=lim?c[pos]:9,ans=0;
    for(int i=0; i<=last; i++)
        if(pre==6&&i==2||i==4)continue;
        else ans+=dfs(pos-1,i==6,i,lim&&(i==last));
    if(!lim)dp[pos][st]=ans;
    return ans;
}
int slove(int q)
{
    int cnt=0;
    while(q)c[cnt++]=q%10,q/=10;
    return dfs(cnt-1,0,-1,1);
}
int main()
{
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int x,y;
    while(cin>>x>>y,x+y)
    {
        memset(dp,-1,sizeof dp);
        cout<<slove(y)-slove(x-1)<<"\n";
    }
    return 0;
}

Amount of Degrees

 URAL - 1057 

Create a code to determine the amount of integers, lying in the set [ XY] and being a sum of exactly K different integer degrees of B.
Example. Let X=15, Y=20, K=2, B=2. By this example 3 numbers are the sum of exactly two integer degrees of number 2:
17 = 2 4+2 0
18 = 2 4+2 1
20 = 2 4+2 2.

Input

The first line of input contains integers X and Y, separated with a space (1 ≤ X ≤  Y ≤ 2 31−1). The next two lines contain integers K and B (1 ≤ K ≤ 20; 2 ≤  B ≤ 10).

Output

Output should contain a single integer — the amount of integers, lying between Xand Y, being a sum of exactly K different integer degrees of B.

Example

inputoutput
15 20
2
2
3

也不难吧,论文题里的模板题

#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lson l,(l+r)/2,rt<<1
#define rson (l+r)/2+1,r,rt<<1|1
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define pb push_back
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define pll pair<long long,long long>
#define pii pair<int,int>
#define pq priority_queue
const int N=32,MD=1e9+7,INF=0x3f3f3f3f;
const ll LL_INF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-9,e=exp(1),PI=acos(-1.);
int c[N],dp[N][N];
int x,y,k,b;
int dfs(int pos,int st,int lim)
{
    if(st>k||st+pos+1<k)return 0;
    if(pos<0)return st==k;
    if(!lim&&dp[pos][st]!=-1)return dp[pos][st];
    int last=lim?c[pos]:b-1,ans=0,mi=min(last,1);
    for(int i=0;i<=mi;i++)ans+=dfs(pos-1,st+i,lim&&(i==last));
    if(!lim)dp[pos][st]=ans;
    return ans;
}
int slove(int q)
{
    int cnt=0;
    while(q)c[cnt++]=q%b,q/=b;
    return dfs(cnt-1,0,1);
}
int main()
{
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    cin>>x>>y>>k>>b;
    memset(dp,-1,sizeof dp);
    cout<<slove(y)-slove(x-1);
    return 0;
}

上海邀请赛的

链接:https://www.nowcoder.com/acm/contest/163/J
来源:牛客网

Beautiful Numbers
时间限制:C/C++ 8秒,其他语言16秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

NIBGNAUK is an odd boy and his taste is strange as well. It seems to him that a positive integer number is beautiful if and only if it is divisible by the sum of its digits.
We will not argue with this and just count the quantity of beautiful numbers from 1 to N.

输入描述:

The first line of the input is T(1≤ T ≤ 100), which stands for the number of test cases you need to solve.
Each test case contains a line with a positive integer N (1 ≤ N ≤ 10
12
).

输出描述:

For each test case, print the case number and the quantity of beautiful numbers in [1, N].
示例1

输入

复制
2
10
18

输出

复制
Case 1: 10
Case 2: 12

很难想到从数位和出发

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[13];
ll dp[109][13][109][109],n;
ll dfs(int pos,int st,int sum,int mod,bool lim)
{
    if(pos<0) return mod==0&&st==sum;
    if(sum>st||sum+9*(pos+1)<st)return 0;
    if(!lim&&dp[st][pos][sum][mod]>=0) return dp[st][pos][sum][mod];
    ll ans=0;
    int mi=lim?a[pos]:9;
    for(int i=0;i<=mi;i++)ans+=dfs(pos-1,st,sum+i,(mod*10+i)%st,lim&&i==mi);
    if(!lim) dp[st][pos][sum][mod]=ans;
    return ans;
}
ll cal(ll n)
{
    int pos=0;
    while(n) a[pos++]=n%10,n/=10;
    ll ans=0;
    for(int i=1;i<=108;i++)ans+=dfs(pos-1,i,0,0,1);
    return ans;
}
int main()
{
    int T,ca=0;
    memset(dp,-1,sizeof(dp));
    scanf("%d",&T);
    while(T--)scanf("%lld",&n),printf("Case %d: %lld\n",++ca,cal(n));
    return 0;
}

 

posted @ 2018-08-09 17:01  暴力都不会的蒟蒻  阅读(265)  评论(0编辑  收藏  举报