題集見大佬部落格
入門題,檢驗剛才自己有沒有看懂
注意一些細節。
的確挺套路的
#include#define rep(i, a, b) for(register int i = (a); i < (b); i++)#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using
namespace
std;
const
int maxn = 15
;int a[maxn], dp[maxn][maxn][maxn], len; //
dp陣列記錄除了lead和limit以外其他的東西
int dfs(int pos, int pre, int lead, int sum, int
limit)
return (!limit && !lead) ? dp[pos][pre][sum] = res : res; //
記憶化的時候記得limit和lead
}int part(int
x)int
main()
return0;
}
繼續套路
#include#define rep(i, a, b) for(register int i = (a); i < (b); i++)#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using
namespace
std;
const
int maxn = 15
;int
a[maxn], dp[maxn][maxn][maxn], len;
int dfs(int pos, int pre, int ans, int lead, int
limit)
return (!limit && !lead) ? dp[pos][pre][ans] =res : res;
}int part(int
x)int
main()
第一次這麼輕鬆做出紫題
一樣套模板,爽啊
#include#define rep(i, a, b) for(register int i = (a); i < (b); i++)#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using
namespace
std;
typedef
long
long
ll;const
int maxn = 20
;const
int maxm = 1e6 + 10
;ll dp[maxn][maxn];
inta[maxn], len;
ll dfs(
int pos, int ans, int lead, int limit, int
key)
return (!lead && !limit) ? dp[pos][ans] =res : res;
}ll part(ll x,
inti)
inline ll work(ll a, ll b,
inti)
intmain()
注意數字很大,要用字串儲存
然後就沒啥了,又獨立做出紫題
#include#define add(a, b) a = (a + b) % mod#define rep(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using
namespace
std;
const
int maxn = 12
;const
int maxm = 1e3 + 10
;const
int mod = 1e9 + 7
;int dp[maxm][maxn][maxn][2
];int
a[maxm], len;
char
s1[maxm], s2[maxm];
int dfs(int pos, int pre, int ppre, int ans, int lead, int
limit)
return (!lead && !limit) ? dp[pos][pre][ppre][ans] =res : res;
}int part(char*s)
int judge(char*s)
intmain()
一開始想的時候當前的數肯定是不能記到答案裡的
當然如果知道模數,一直取模就可以限制範圍,就很好了
但問題是我們並不知道模數,這就比較尷尬了
就一直卡在這
然而正解非常暴力,但卻是對的。
既然不知道模數,那就列舉模數
最後判斷一下數字和是不是當前模數且能否整除就好了。
我為什麼沒想到呢?
注意數字dp要開long long
#include#define rep(i, a, b) for(register int i = (a); i < (b); i++)#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using
namespace
std;
typedef
long
long
ll;const
int maxn = 20
;ll dp[maxn][maxn*10][maxn*10
];int
a[maxn], len, mod;
ll dfs(
int pos, int num, int state, int lead, int
limit)
return (!lead && !limit) ? dp[pos][num][state] =res : res;
}ll part(ll x)
return
res;
}int
main()
用二進位制統計就好了
不過很奇怪的是一開始我陣列開的大小是50
因為用程式輸出1e15最多的位數是47
但是交上去會wa乙個點
改成51就過了
以後只要空間剩餘多,就多開一些吧,程式中有些神奇的地方可能會比理論上最大值超出一些
#include#define mul(a, b) a = (a * b) % mod#define rep(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using
namespace
std;
typedef
long
long
ll;const
int maxn = 51
;const
int mod = 10000007
;ll dp[maxn][maxn];
inta[maxn], len;
ll dfs(
int pos, int ans, int lead, int
limit)
return (!limit && !lead) ? dp[pos][ans] =res : res;
}ll part(ll x)
intmain()
總結感覺都是套路,掌握套路就好了
相信自己已經掌握了數字dp
數字dp 板子題
題目傳送 存乙個狀態就可以了,用來判斷前一位是不是6的情況 具體看 注釋 ac include inline long long read while c 0 c 9 return x s using namespace std define newnode treenode malloc size...
換根dp題集
題目鏈結 題意 給你一棵樹,按順序輸出以每個頂點為根節點,到任意點的邊權和最大,輸出這個最大值。思路 換根dp,兩遍dfs,第乙個dfs求出以這個點為根節點,子樹的最大邊權值,儲存在d陣列中。第二個dfs1,首先算出以u節點為根節點的dp值,儲存在ans陣列裡,然後求出u節點的兒子的字首dp值儲存在...
數字dp 計數問題 模板題 數字dp
數字dp目前見的比較少,最為經典的莫過於不要62,或許以前都是暴力求解。例如求解1 n中,數字x出現的次數這類題,暴力列舉每個數的時間複雜度為 o n o n o n 再列舉每一位的時間複雜度為 log 10nlog n log10n 數字一大妥妥超時。值得一提的是,2020 的藍橋杯,第一道簽到題...