對於數字dp,有個挺正常的套路。
首先一般拆分數字。將數字的每一位拿出來,作為上界。
然後設定狀態,一般是填到第幾位,然後根據題目設定,比如說windy就要看上一位是誰,不要62就看上一位是不是6之類的。
然後注意狀態不能跟數字到底是誰有關。就是要確保後面可以亂放的情況下設定狀態。
拆分完後從高位開始處理。一位一位,用limit來看是否能取到9,反之取到對應數字。然後加起來即可。
因為記憶化的原因,複雜度很小。
windy數
很水,但又前導0的限制,如果一直沒有數,直到個位直接返回9。同時前後兩位差絕對值》=2。然後走就行。
#includeusing namespace std;
#define in read()
int in
while(isdigit(ch))
return cnt*f;
}int a,b;
int dp[14][12];
int cnt,num[123];
int dfs(int pos,int pre,int lead,int limit)
while(isdigit(ch))return cnt*f;
}int dp[14][2];
int num[12],cnt;
int dfs(int pos,int is6,int limit)if(!limit)dp[pos][is6]=tem;return tem;
}int solve(int x)return dfs(cnt,0,1);
}int main()
while(isdigit(ch))return cnt*f;
}struct nodet[3003];int tot;
char ch[2300];
int l,r,k,n;
void insert(char s,int len)rt=t[rt].ch[x];
}t[rt].key=1;
}queueq;
void getfail()
while(!q.empty())else
} }}int num[23],cnt;
int dp[23][1503][2];
int dfs(int pos,int u,int flag,int limit,int lead)else tem+=dfs(pos-1,t[u].ch[i],flag|t[t[u].ch[i]].key,limit&&i==num[pos],lead&&i==0);
} if(!limit&&!lead)dp[pos][u][flag]=tem;return tem;
}int check(int x)if(l==r+1)cout<<"no such number";
else cout暴力搞吧。直接列舉哪一位是力矩,因為這一位是力矩,下一位就肯定不是。所以不重不漏。
注意有負數,整體挪動3000位,反正開的下。
#includeusing namespace std;
#define in read()
#define int long long
int in
while(isdigit(ch))return cnt*f;
}int f[20][20][6000];int num[20],cnt;
int dfs(int pos,int mid,int sum,int lead,int limit)if(!limit&&!lead)f[pos][mid][sum]=tem;
return tem;
}int solve(int x)
int ans=0;
for(int i=1;i<=cnt;i++)return ans;
}signed main()
return 0;
}
數字DP入門 數字DP模板
數字dp是一種計數用的dp,一般就是要統計乙個區間 le,ri 內滿足一些條件數的個數。所謂數字dp,字面意思就是在數字上進行dp咯。數字還算是比較好聽的名字,數字的含義 乙個數有個位 十位 百位 千位.數的每一位就是數字啦!之所以要引入數字的概念完全就是為了dp。數字dp的實質就是換一種暴力列舉的...
數字dp模版(dp)
1 include 2 include 3 include 4 include 5 6using namespace std 78 intt 9long long dp 19 19 2005 10 long long l,r 11int shu 20 12 13long long dfs int l...
數字DP 數字遊戲
科協裡最近很流行數字遊戲。某人命名了一種不降數,這種數字必須滿足從左到右個位數字呈現小於等於的關係,如123,446.現在大家決定玩乙個遊戲,指定乙個整數閉區間 a,b 問這個區間內有多少個不降數。輸入多組測試資料。每組只包含兩個數字a和b 1 a,b 2 31 每行給出乙個測試資料的答案,即 a,...