2024.08.23快手

1. 判断括号字符串有效

给定一个只包括 '(',')','{','}','[',']' 的字符串 s(1 <= s.length <= 1e4) ,
判断字符串是否有效。如果有效,输出有效括号的个数。如果无效,则输出False。

简单的栈
int main() {
    int t;
    cin>>t;
    char match[3][2] = {{'(',')'},{'[',']'},{'{','}'}};
    while(t--){
        string cur;
        cin>>cur;
        stack<int> st;
        bool flag = true;
        int res = 0;
        for(auto c:cur){
            bool corr = false;
            for(int i=0;i<3;i++){
                if(c==match[i][1]){//如果匹配的是后面的右括号
                    if(!st.empty()&&st.top()==match[i][0]){
                        st.pop();
                        corr = true;
                        res++;
                    }
                    else{
                        flag = false;
                        break;
                    }
                }
            }
            if(!corr) st.push(c);//没有抵消掉,入栈
        }
        if(st.empty()&&flag) cout<<res<<endl;
        else cout<<"False"<<endl;
    }
    return 0;
}

2. 滑雪

Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。
Michael想知道载一个区域中最长底滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。

记忆化搜索
int main() {
    int R,C;
    cin>>R>>C;
    vector<vector<int>> grid(R,vector<int>(C));
    for(int i=0;i<R;i++)
        for(int j=0;j<C;j++)
            cin>>grid[i][j];
    vector<vector<int>> dp(R,vector<int>(C));//dp[x][y]表示以x,y为起点的最长路径长度
    int dir[4][2] = {{1,0},{0,-1},{-1,0},{0,1}};
    function<int(int,int)> f = [&](int x,int y)->int{
        if(dp[x][y]!=0) return dp[x][y];
        int res = 0;
        for(int i=0;i<4;i++){
            int nx = x + dir[i][0];
            int ny = y + dir[i][1];
            if(nx<0||ny<0||nx==R||ny==C) continue;
            if(grid[nx][ny]<=grid[x][y]) continue;
            res = max(res,f(nx,ny));
        }
        dp[x][y] = res + 1;
        return dp[x][y];
    };
    int res = 0;
    for(int i=0;i<R;i++){
        for(int j=0;j<C;j++){
            res = max(res,f(i,j));
        }
    }
    cout<<res;
    return 0;
}

3. 挖宝藏

一个人有n体力,m个金币,k个宝藏点,p条双向路径。每个宝藏点都需要一定的金币v才能挖掘获取价值w。
每次通过一条路径都需要花费t的体力,可以走重复路径,但是宝藏只能获取一次。你可以选择任意一个点作为起点,问最多能获得多少价值的宝藏。

题意不清楚,数据也有问题,乱写的代码

int main() {
    int n,m,k,p;//持有体力,持有金币,点数目,路径数目
    cin>>n>>m>>k>>p;
    vector<vector<int>> treasure(21,vector<int>(2));//价值和需要的金币
    vector<vector<int>> graph(21,vector<int>(21,INT_MAX/3));//花费体力的代价
    for(int i=0;i<k;i++)
        cin>>treasure[i][0]>>treasure[i][1];
    for(int i=0;i<p;i++){
        int from,to,fee;
        cout<<"开始读取行"<<endl;
        cin>>from>>to>>fee;
        graph[from][to] = min(graph[from][to],fee);
        graph[to][from] = min(graph[to][from],fee);
    }
    cout<<"读取完毕"<<endl;
    for(int kk=0;kk<k;kk++)//弗洛伊德遍历中转点
        for(int i=0;i<k;i++)
            for(int j=0;j<k;j++)
                graph[i][j] = min(graph[i][j],graph[i][kk]+graph[kk][j]);
    cout<<"弗洛伊德计算完毕"<<endl;       
    //dp[i][j][k][state]表示以i为起点,剩余体力为j,剩余金币为k,已经挖取点状态为state的最大宝藏价值获取量
    vector<vector<int>> dp(k+1,vector<int>(1<<(k+1),-1));

    function<int(int,int,int,int)> f = [&](int x,int state,int sum1,int sum2)->int{
        cout<<"遍历"<<x<<"点"<<endl;  
        if(dp[x][state]!=-1) return dp[x][state];
        int res = 0;
        for(int i=0;i<k;i++){//遍历所有点
            if(!(state&(1<<i))){//第i个点没有挖掘
                if((sum1+graph[x][i]<=n)&&(sum2+treasure[i][1]<=m)){//体力和金币都满足要求
                    res = max(res,f(i,state|(1<<i),sum1+graph[x][i],sum2+treasure[i][1])+treasure[i][0]);
                }
            }
        }
        dp[x][state] = res;
        return res;
    };
    cout<<f(0,0,0,0)<<endl;
    return 0;
}
posted @   失控D大白兔  阅读(6)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示