Warning: session_start(): open(/tmp/sess_a257967f67e0f6f4e288927ccaf42c71, O_RDWR) failed: No space left on device (28) in /data/wiki/inc/init.php on line 239

Warning: session_start(): Failed to read session data: files (path: ) in /data/wiki/inc/init.php on line 239

Warning: Cannot modify header information - headers already sent by (output started at /data/wiki/inc/init.php:239) in /data/wiki/inc/auth.php on line 430

Warning: Cannot modify header information - headers already sent by (output started at /data/wiki/inc/init.php:239) in /data/wiki/inc/actions.php on line 38

Warning: Cannot modify header information - headers already sent by (output started at /data/wiki/inc/init.php:239) in /data/wiki/lib/tpl/dokuwiki/main.php on line 12
2020-2021:teams:legal_string:jxm2001:动态规划_1 [CVBB ACM Team]

用户工具

站点工具


2020-2021:teams:legal_string:jxm2001:动态规划_1

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
2020-2021:teams:legal_string:jxm2001:动态规划_1 [2020/09/25 22:22]
jxm2001 [算法练习]
2020-2021:teams:legal_string:jxm2001:动态规划_1 [2021/01/28 20:37] (当前版本)
jxm2001
行 310: 行 310:
 $|x-y|\le m$ 等价于增量 $n-m\le d\le n+m$,考虑计算出 $d\le n+m$ 的值减去 $d\le n-m-1$ 的值即可。 $|x-y|\le m$ 等价于增量 $n-m\le d\le n+m$,考虑计算出 $d\le n+m$ 的值减去 $d\le n-m-1$ 的值即可。
  
-另外注意 $n-m\le 0$ 的情况需要特判防止 $\text{dp}$ 出错。+另外注意 $n-m\le 0$ 的情况需要特判防止 $\text{dp}$ 出错,由于 $|x-y|\le n$ 必成立,所以结果为 $0$
  
 搜索函数为 $f(pos,​eq1,​eq2,​eq3)$。其中 $eq1$ 表示 $x$ 前缀是否与 $A$ 前缀相等,$eq2$ 表示 $y$ 前缀是否与 $B$ 前缀相等。 搜索函数为 $f(pos,​eq1,​eq2,​eq3)$。其中 $eq1$ 表示 $x$ 前缀是否与 $A$ 前缀相等,$eq2$ 表示 $y$ 前缀是否与 $B$ 前缀相等。
行 362: 行 362:
 </​hidden>​ </​hidden>​
  
 +=== 习题七 ===
 +
 +[[https://​www.luogu.com.cn/​problem/​CF908G|CF908G]]
 +
 +== 题意 ==
 +
 +定义 $S(x)$ 表示将 $x$ 的每个位从小到大重排后的值,例如 $S(3190)=0139,​S(4312)=1234$。
 +
 +给定 $1\le X\le 10^{700}$,求
 +
 +$$
 +\sum_{i=1}^X S(i)
 +$$
 +
 +== 题解 ==
 +
 +考虑按贡献计算,设 $f(i,j)$ 表示 $1\sim X$ 中满足 $S(x)$ 的第 $j$ 位等于 $i$ 的 $x$ 的个数,$n=\text{len}(X)$,于是
 +
 +$$
 +ans=\sum_{i=1}^9i\sum_{j=1}^n f(i,​j)10^{j-1}=\sum_{i=1}^{9}i\sum_{j=1}^n (g(i,​j)-g(i+1,​j))10^{j-1}
 +$$
 +
 +其中 $g(i,​j)=\sum_{k=i}^9f(i,​k)$ 表示 $1\sim X$ 中满足 $S(x)$ 的第 $j$ 位大于等于 $i$ 的 $x$ 的个数。
 +
 +不难发现 $g(i,j)$ 也等于 $1\sim X$ 中满足 $x$ 中至少有 $j$ 位大于等于 $i$ 的 $x$ 的个数,于是
 +
 +$$
 +g(i,​j)=\sum_{k=j}^n \text{dp}(i,​k)
 +$$
 +
 +其中 $\text{dp}(i,​j)$ 表示 $1\sim X$ 中满足 $x$ 中有 $j$ 位大于等于 $i$ 的 $x$ 的个数,显然该值通过数位 $\text{DP}$ 即可计算。
 +
 +时间复杂度 $O(100n^2)$。
 +
 +<hidden 查看代码>​
 +<code cpp>
 +const int MAXL=705,​Mod=1e9+7;​
 +char s[MAXL];
 +int a[MAXL],​dp[10][MAXL][MAXL][2],​suf[11][MAXL];​
 +int dfs(int v,int pos,int cnt,bool eq){
 + if(!pos||cnt<​0)return cnt==0;
 + if(~dp[v][pos][cnt][eq])return dp[v][pos][cnt][eq];​
 + int ans=0,​mv=eq?​a[pos]:​9;​
 + _rep(i,​0,​mv)
 + ans=(ans+dfs(v,​pos-1,​cnt-(i>​=v),​eq&&​(a[pos]==i)))%Mod;​
 + return dp[v][pos][cnt][eq]=ans;​
 +}
 +int main()
 +{
 + mem(dp,​-1);​
 + scanf("​%s",​s+1);​
 + int len=strlen(s+1);​
 + for(int i=1,​j=len;​i<​=len;​i++,​j--)a[i]=s[j]-'​0';​
 + int ans=0;
 + _for(i,​1,​10)for(int j=len;​j>​=1;​j--)
 + suf[i][j]=(suf[i][j+1]+dfs(i,​len,​j,​true))%Mod;​
 + _for(i,​1,​10){
 + int p=1;
 + _rep(j,​1,​len){
 + ans=(ans+1LL*i*p%Mod*(suf[i][j]-suf[i+1][j]+Mod)%Mod)%Mod;​
 + p=10LL*p%Mod;​
 + }
 + }
 + enter(ans);​
 + return 0;
 +}
 +</​code>​
 +</​hidden>​
2020-2021/teams/legal_string/jxm2001/动态规划_1.1601043739.txt.gz · 最后更改: 2020/09/25 22:22 由 jxm2001