动态规划训练

动态规划这玩意在ACM中比较重要,但个人对其理解不深,所以想刷刷相关题目,就在此记录下所刷题目(点击标题可进入原题地址)

1、被3整除的子序列

描述

给你一个长度为50的数字串,问你有多少个子序列构成的数字可以被3整除,答案对1e9+7取模

思路

对于一个整数,如果其所有位数之和是3的倍数,那么这个整数也就是3的倍数,证明很容易,这里略过。
那么,假设dp[i][j]表示前i个数字中的子序列,对3取余为j的数量,则dp[i+1][j]就可由前面和第i+1个数字推出。
举个例子,第i+1个数字取余3为2,那么
dp[i+1][0] += dp[i][1] //前面i个子序列中,余数为1的组合,加上余数为2便是余数为0了
dp[i+1][1] += dp[i][2] //前面i个子序列中,余数为2的组合,加上余数为2便是余数为1了
dp[i+1][2] += dp[i][0]+ 1 //前面i个子序列中,余数为0的组合,加上余数为2便是余数为2,同时还得加上第i+1个数字本身
其他情况同理,此外,由于每次只需用到前面i个子序列的情况,而1--i-1不需用到,所有dp还可优化到一维。

代码

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int mod = 1e9+7;
int dp[5];
int main(){
    char x[55];
    while(cin >> x){
        memset(dp,0,sizeof(dp));
        int len = strlen(x);
        for(int i = 0;i < len;i++)
            x[i]-='0';
        dp[x[0]%3] = 1;
        for(int i = 1;i < len;i++){
            if(x[i]%3 == 0){
                dp[0] = (dp[0]<<1)+1;
                dp[1]<<=1;
                dp[2]<<=1;
            }
            else if(x[i]%3 == 1){
                int temp0 = dp[0],tmep1 = dp[1];
                dp[0]+=dp[2];
                dp[1]+=temp0+1;
                dp[2]+=tmep1;
            }
            else{
                int temp0 = dp[0];
                dp[0]+=dp[1];
                dp[1]+=dp[2];
                dp[2]+=temp0+1;
            }
            for(int i = 0;i < 3;i++)
                dp[i]%=mod;
        }
        cout << dp[0] << endl;
    }
    return 0;
}

2、牛牛的计算机内存

描述

牛牛的计算机一共有m块内存,现在有n条指令,每条指令是一个01序列
如果指令的第i个字符为1,说明这条指令需要访问第i块内存
每条指令的执行代价为k^2, k为新访问内存的数量,即之前的指令都没有访问到的内存数量
你可以随意安排n条指令的执行顺序,求执行完所有指令的最小代价
(n,m <= 20)

思路

n条指令,可以用二进制代表其是否已执行,如1001表示第1和第4条指令已执行,第2和第3条指令未执行
那么,状态转移,从结果回推到开始,举个例子
此时n=4,假设要执行完所有4条指令指令,即令二进制为1111
那么,其前面情况必然是0111,1011,1101,1110这四种情况之一,取他们加上执行未执行指令的代价,取最小即可
而这些可通过[0,1<<n)一重循环表示情况,接下来[1,n]是第二重循环表示选择指令解决。
部分题解弄了个滚动数组,又多加了[1,n]循环,即三重循环,其实完全没必要。

代码

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int inf = 0x3f3f3f3f;
char a[25][25];
int b[25],dp[1<<20],val[1<<20];
int to_ten(char x[]){
    int ans = 0;
    for(int i = strlen(x)-1,j = 1;i >= 0;i--,j<<=1)
        ans+=(x[i] == '1')?j:0;
    return ans;
}
int get_value(int x,int y){
    int ans = 0;
    for(int i = 0;i < 21;i++)
        if((x&(1<<i)) && !(y&(1<<i))) ans++;
    return ans*ans;
}
int main(){
    int n,m;
    cin >> n >> m;
    memset(dp,0x3f,sizeof(dp));
    dp[0] = 0;
    for(int i = 0;i < n;i++){
        cin >> a[i];
        b[i] = to_ten(a[i]);
    }      
    for(int j = 0;j < (1<<n);j++){
        if(dp[j] == inf) continue;
        for(int u = 0;u < n;u++){
            if(!(j&(1<<u))){
                int temp = dp[j]+get_value(b[u],val[j]);
                if(temp < dp[j|(1<<u)]){
                    dp[j|(1<<u)] = temp;
                    val[j|(1<<u)] = b[u]|val[j];
                }
            }
        }
    }
    cout << dp[(1<<n)-1] << endl;
    return 0;
}
全部评论

相关推荐

1.&nbsp;自我介绍2.&nbsp;项目都是自己写的吗?3.&nbsp;我看你用&nbsp;koa2&nbsp;写后端,为什么选择它,能讲讲吗?4.&nbsp;那你提到&nbsp;koa2&nbsp;它是不提供中间件的,你是怎么解决的?5.&nbsp;中间件的原理是什么?(洋葱模型)6.&nbsp;你刚刚说碰到&nbsp;next()&nbsp;就进入下一个中间件,那&nbsp;next&nbsp;只能执行同步,如果是异步的话,你是怎么处理的?(async/await,但是我发现,有的中间件需要在异步中间件之前执行,所以我用&nbsp;try/catch&nbsp;来处理异步中间件的异常)7.&nbsp;JS&nbsp;异步发展史,以及它们的优缺点说一下&nbsp;(回调函数--Promise--Generator--async/await)8.&nbsp;你刚刚说&nbsp;Promise&nbsp;状态不能更改,那如果我要设计一个能修改&nbsp;Promise&nbsp;状态的函数,你会怎么设计?9.&nbsp;CSS&nbsp;水平垂直居中的方法(flex、grid、绝对定位&nbsp;+&nbsp;margin:auto、绝对定位&nbsp;+&nbsp;负&nbsp;margin、绝对定位&nbsp;+&nbsp;transform、table-cell)10.&nbsp;你刚刚说到&nbsp;flex&nbsp;布局,那&nbsp;flex:1&nbsp;是什么意思?(flex:&nbsp;flex-grow&nbsp;&nbsp;flex-shrink&nbsp;&nbsp;flex-basis;等价&nbsp;flex:1&nbsp;1&nbsp;0%表示元素可以均分剩余空间,可拉伸、可压缩,不依赖内容宽度,自动自适应填充布局。)11.&nbsp;父容器宽是&nbsp;500px,然后它左右各有两个子容器是&nbsp;100px,如果设置&nbsp;flex:&nbsp;1,那它的宽度是多少?(500-100-100=300px)12.&nbsp;说说你对浏览器缓存的理解(强缓存、协商缓存)13.&nbsp;如果一个用户,他怎么去刷新都无法刷到最新版的代码,你能说下可能的原因吗?(版本号、hash等)还有吗?(我说我不知道了,面试官说还有&nbsp;CDN&nbsp;没有同步,我说企业才会这么干,自己写项目一般不会,我知道&nbsp;cdn&nbsp;是用来解决高并发的手段)14.&nbsp;React你熟吗?说下&nbsp;React&nbsp;函数组件和类组件的区别15.&nbsp;怎么避免&nbsp;Hooks&nbsp;导致组件重新渲染?(使用&nbsp;useCallback、useMemo、React.memo、useRef等等)16.&nbsp;谈一下我对&nbsp;React&nbsp;的状态管理的理解(Redux、Mobx、Zustand,我说&nbsp;Zustand&nbsp;用的最多)17.&nbsp;React&nbsp;常见的&nbsp;hooks&nbsp;有哪些?(useState、useEffect、useRef、useCallback、useMemo、useReducer、useContext、useImperativeHandle、useLayoutEffect、useDebugValue)18.&nbsp;TS&nbsp;你熟吗?我们引进&nbsp;TS&nbsp;的目的是为什么?19.&nbsp;interface&nbsp;和&nbsp;type&nbsp;的区别20.&nbsp;说下&nbsp;TS&nbsp;里的泛型21.&nbsp;我现在有十个字段,比如十个字段就要&nbsp;A&nbsp;B&nbsp;C&nbsp;D&nbsp;E&nbsp;F&nbsp;G&nbsp;这种。那我现在另有另外一个方法,这个方法接受的参数呢,必须是这个&nbsp;interface&nbsp;A&nbsp;里面的这个&nbsp;K。就比如说你可以是&nbsp;A&nbsp;B&nbsp;C&nbsp;可以&nbsp;A&nbsp;B&nbsp;C&nbsp;D&nbsp;任何组合都可以,但是必须是这个&nbsp;interface&nbsp;里面的&nbsp;A&nbsp;里面的定义的。这个&nbsp;K&nbsp;这种类型的话是怎么去定义呢?(说实话我有点不太理解啥意思,反正我说了&nbsp;keyof)```&nbsp;TypeScriptinterface&nbsp;Obj&nbsp;{A:&nbsp;stringB:&nbsp;stringC:&nbsp;stringD:&nbsp;stringE:&nbsp;string//&nbsp;其他字段...}```22.&nbsp;vite&nbsp;用过吗?说说和&nbsp;webpack&nbsp;的区别。vite&nbsp;的优缺点是什么23.&nbsp;说说&nbsp;Tree&nbsp;shaking(树摇)&nbsp;和&nbsp;Code&nbsp;Splitting&nbsp;(代码分割)的区别24.&nbsp;Git&nbsp;你熟吗?说说&nbsp;git&nbsp;merge&nbsp;和&nbsp;git&nbsp;rebase&nbsp;的区别,什么时候用&nbsp;git&nbsp;merge,什么时候用&nbsp;git&nbsp;rebase?25.&nbsp;web3&nbsp;你熟吗?(不太熟,听说过而已)26.&nbsp;我看你自我介绍说了&nbsp;AI,你是怎么用的?27.&nbsp;除了提示词,还有什么能让&nbsp;AI&nbsp;更聪明?28.&nbsp;AI&nbsp;的优缺点你说一下29.&nbsp;AI&nbsp;发展这么快,你觉得我们以后会扮演什么角色?30.&nbsp;反问基本都答上来了。面了我80分钟,我还以为稳过的
查看29道真题和解析
点赞 评论 收藏
分享
03-29 17:05
门头沟学院 Java
asdasdasda...:我前段时间找工作焦虑,有几天连续熬夜熬穿了,然后心脏突然不舒服,立马躺床上睡觉了,然后第二天还是不舒服,去看医生说是心率不齐,吓得我后面天天早早睡觉,调养身体,过了好几天才好过来。所以真的,工作这些东西哪有那么重要,最多钱多一点钱少一点,降低物欲。活着才是最重要的,现在想想真的后怕
如何排解工作中的焦虑
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务