标签:
(一)数位DP
input | output |
---|---|
15 20 2 2 |
3 |
一道据说比较经典的题目,基本弄懂,ans++ 那里实在没搞懂,不过也没那么多时间给我犹豫。。
主要借助一个状态转移方程 f[i][j] = f[i-1][j-1] + f[i-1][j]
f[i][j] 表示二进制中前i位中有j个1的个数,其他进制的数在转换过来之后都可一借用f[i][j]来解决。可以借助这个图理解一下这个方程。
不过ans++那里实在每看懂。
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> #include<iomanip> #include<fstream> #include<vector> typedef long long LL; using namespace std; const int maxN = 50; int f[maxN][maxN]; void getMap (){ f[0][ 0] = 1; for( int i = 1 ; i< maxN ;++i){ f[i][0] = 1; for( int j= 1 ; j<=i ;++j) f[i][j] = f[i-1][j] + f[i-1][j-1] ; } } int solve ( int x, int k , int c) { vector< int > arr; while( x) { arr.push_back ( x% c); x /= c; } int ans = 0, cnt = 0 ; for( int i = arr.size() -1 ; i>= 0 ; --i){ if( arr[i] == 1){ ans += f[i][ k - cnt]; cnt++ ; if( cnt == k ) break; } else if( arr[i] > 1){ ans += f[i+1][k - cnt]; break; } } if( cnt == k ) ans ++; return ans ; } int main() { for( int i = 0 ; i< maxN ; ++i) for( int j = 0 ; j< maxN; ++j) f[i][j] = 0 ; int x, y ; int k, b; getMap(); cin>>x>>y>>k>>b; cout<<solve(y,k,b) - solve(x-1 , k , b)<<endl; return 0; }
(二)树形DP
标签:
原文地址:http://www.cnblogs.com/topW2W/p/5163815.html