1. 程式人生 > >Balanced Number HDU - 3709 數位dp

Balanced Number HDU - 3709 數位dp

左右 while con cto sta ons names limit tor

題意: 給出範圍 算出 滿足 選取一個數中任一一個 樹作為支點 兩邊的數分別乘以到中心的距離和 左和等於右和 的數有多少個

數位DP題 狀態轉移方程為dp[pos][x][state]=dp[pos-1][x][state-(pos-x)*i] 表示為pos位上的數字為 i 以x為支點 則 以中心點左為負右為正 pos左右的數乘以權值的 和為state pos-1位就是 把pos位的 i乘以權值減去 即 state-(pos-x)*i 如果枚舉到最後一位的時候 state==0就說明平衡了 其中 0 00 000 000 ......也是平衡的 出了0其他都是非法的要減去

#include <cstdio>
#include 
<cmath> #include <algorithm> #include<vector> #include<iostream> #include<cstring> using namespace std; typedef long long ll; const int MOD=2520; int cnt; ll a[100]; int t[300]; ll dp[20][20][3000]; ll dfs(int pos,int x,int state,bool limit ){ if(pos==-1)return !state; if
(!limit&&dp[pos][x][state]!=-1)return dp[pos][x][state]; int up=limit?a[pos]:9; ll ans=0; for(int i=0;i<=up;i++){ ans+=dfs(pos-1,x,state+i*(pos-x),limit&&up==i); } if(!limit) dp[pos][x][state]=ans; return ans; } ll solve(ll x){ int pos=0; while(x){ a[pos
++]=x%10; x/=10; } ll ans=0; for(int i=0;i<pos;i++)ans+=dfs(pos-1,i,0,1); return ans-pos+1;// 減去00 000 000 其中單0算 所以加一 } int main() { ll a,b; int t; cin>>t; memset(dp,-1,sizeof(dp)); while(t--){ cin>>a>>b; printf("%I64d\n",solve(b)-solve(a-1)); } return 0; }

Balanced Number HDU - 3709 數位dp