首页 > 其他分享 >kuangbin专题12 基础DP

kuangbin专题12 基础DP

时间:2022-09-23 11:44:48浏览次数:87  
标签:std maxx 12 int maxn DP kuangbin include dp

 

Longest Ordered Subsequence

题意:有n个数,在保证原有顺序不变的前提下取出尽可能多的数,使得形成的新序列严格递增。输出取出的数个数。

           题解:有两层循环,第二层循环判断第j个位置能不能要[i], 能的话就与当前值比较去max,这需要满足i位置的dp已达最优,所以第一层循环是用来保证每个dp[i]已达最优的。但是没法记录路径,也就是说最大值确实能找到,但是可能有很多路径都满足。

  dp[i]:包含第i项,且第i项是最后一个被选中的的最长子序列长度。

#include<iostream>
#include<cstring>
#include<cstdlib>
using namespace std;
#define ll long long
const int maxn = 1050;
int n, a[maxn]; 
ll dp[maxn];
int main()
{    
    cin >> n;
    for(int i = 1; i <= n; i ++) {
        cin >> a[i];        
        dp[i] = 1;
    }
    ll maxx = 0;
    //无法记录路径,也就是:最多确实是那么些个,但是到底是那几个点,情况可能有好多 
    for(int i = 1; i <= n; i ++) {//dp[i]已达最优 
        for(int j = i + 1; j <= n; j ++) {
            if(a[j] > a[i]) {//a[i]能不能选 
                dp[j] = max(dp[i] + 1, dp[j]);
            }
        }
        maxx = max(maxx, dp[i]);
    }
    cout << maxx << "\n";
    return 0;
}

 

Super Jumping! Jumping! Jumping!

题意:给定一条长度为n的序列,其中存在一条元素和最大的严格上升子序列,求这条序列的元素和。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 1050;
ll a[maxn], dp[maxn];
int main()
{
    int n;
    while(cin >> n && n) {
        for(int i = 1; i <= n; i ++) {
            cin >> a[i];
            dp[i] = a[i];
        }
        ll maxx = 0;
        for(int i = 1; i <= n; i ++) {
            for(int j = i + 1; j <= n; j ++) {
                if(a[j] > a[i]) {
                    dp[j] = max(dp[j], dp[i] + a[j]);
                }
            }
            maxx = max(maxx, dp[i]);
        }
        cout << maxx << "\n";
    }
    
    return 0;
}

 

Common Subsequence

题意:首先对最长子序列有个定义:如果一个字符串a可以由另一个字符串b删去某些元素得到,那么说明a就是b的子序列字符串。现在有两个字符串,请问最长公共子序列是多长?
#include<iostream>
#include<cstdlib>
#include<cstring>
using namespace std;
const int maxn = 1005;
int dp[maxn][maxn];
int main()
{
    char s1[maxn], s2[maxn];
    while(~scanf("%s%s",s1 + 1, s2 + 1)) {
        memset(dp, 0, sizeof(dp));
        int l1 = strlen(s1 + 1);
        int l2 = strlen(s2 + 1);
        for(int i = 1; i <= l1; i ++) {
            for(int j = 1; j <= l2; j ++) {
                if(s1[i] == s2[j]) dp[i][j] = dp[i - 1][j - 1] + 1;
                else {
                    dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
                }
            }
        }
        cout << dp[l1][l2] << "\n";
    }
    
    return 0;
}

 

Ignatius and the Princess IV

题意:给出n个数,出题人想找出出现至少(n+1)/2次的数, 现在需要你帮忙找出这个数是多少?
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 20;
int a[maxn], n;
//odd:奇数 出现最多的数 - 其他数总和 >= 1
int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
    while (cin >> n) {
        int sum = 0, ans;
        for (int i = 1; i <= n; i ++) {
            cin >> a[i];
            if (sum == 0) {
                sum ++;
                ans = a[i];
            } else {
                if (ans == a[i]) sum ++;
                else sum --;
            }
        }
        cout << ans << "\n";
    }
    return 0;
}

 

Phalanx

给你一个矩阵,只由小写或大写字母构成。求出它的最大对称子矩阵的边长。其中对称矩阵是一个k*k的矩阵,它的元素关于从左下角到右上角的对角线对称。

 

 题解:dp[i][j]代表以(i,j)为右下角顶点的矩阵中,最大的对称矩阵的边长。每次dp[i][j]都以dp[i-1][j-1]为参考,只遍历一行一列,且遍历的k值小于dp[i-1][j-1]。

 初始化:dp[i][j] = 1

 需要注意的是,当遇到不满足对称条件的两个顶点时,循环结束。但这并不意味着dp[i][j]只能等于1,它的值应该是遍历结束时f的值 + 1。

#include<bits/stdc++.h>
using namespace std;
#define TLE std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
const int maxn = 1050;
char a[maxn][maxn];
int n;
int dp[maxn][maxn];
int main() {
    TLE;
    while (cin >> n && n) {
        for (int i = 1; i <= n; i ++) {
            for (int j = 1; j <= n; j ++) {
                dp[i][j] = 1;
            }
        }

        for (int i = n; i >= 1; i --) {
            for (int j = 1; j <= n; j ++) {
                cin >> a[i][j];
            }
        }
        int maxx = 1;
        for (int i = 2; i <= n; i ++) {
            for (int j = 2; j <= n; j ++) {
                int f = 0;
                int t = dp[i - 1][j - 1];
                for (int k = 1; k <= t; k ++) {
                    if (a[i - k][j] != a[i][j - k]) {//写成dp了
                        break;
                    }
                    f ++;
                }
                if (f) {
                    dp[i][j] += f;
                }
                maxx = max(maxx, dp[i][j]);
            }
        }
        cout << maxx << "\n";
    }

    return 0;
}

 

标签:std,maxx,12,int,maxn,DP,kuangbin,include,dp
From: https://www.cnblogs.com/coding-inspirations/p/16722131.html

相关文章

  • WPF播放音频使用的SoundPlayer和MediaPlayer
    WPF中,最简单最容易播放音频的方式是使用SoundPlayer类。它是.NETFramework2.0的一部分,是对Win32PlaySoundAPI的封装。         它具有以下限制:1)仅支持.wav......
  • LeetCode1235 规划兼职工作
    LeetCode1235规划兼职工作按照结束时间进行排序\(f[i]\)表示前\(i\)个工作的最大报酬,第\(i\)个工作可选可不选第\(i\)个不拿:\(f[i]=max(f[i],f[i-1])\)第\(......
  • P1078 [NOIP2012 普及组] 文化之旅
    https://www.luogu.com.cn/problem/P1078搜索,图论,剪枝,最短路绿色题思路一:搜索1.输入,建边,用一个数组存储已经学习的文化,2.搜索,以当前的点now去看能走到哪些边,......
  • 【源码笔记】ThreadPoolExecutor#execute
    /***Executesthegiventasksometimeinthefuture.Thetask*mayexecuteinanewthreadorinanexistingpooledthread.**Ifthetaskcannotbesu......
  • javascript: 复制对象时的深拷贝及浅拷贝(chrome 105.0.5195.125)
    一,js代码<html><head><metacharset="utf-8"/><title>测试</title></head><body><buttononclick="assign()">无效:变量直接赋值</button><br/><br/><br......
  • 设计模式之(12)——外观模式
    外观模式(facadePattern)又叫门面模式,隐藏了子系统的复杂实现,为子系统中的一组接口提供了一个统一的访问入口,使得子系统容易被访问或使用,说白了就是把复杂的子系统封装成......
  • 2022.9.12———HZOI【CPS-S开小灶3】游寄
    \(Preface\)\(Rank35/41\)\(80pts+0pts=80pts\)蒻爆了\(\mathfrak{T1}\世界冰球锦标赛\)这就是我在这里说的那个更板的题,全场就我一个人打记搜,别人没\(A\)都是写......
  • 2022.9.12———HZOI【CSP-S模拟4】游寄
    \(Preface\)\(Rank32/43\)\(0pts+40pts+40pts+20pts=100pts\)\[\Huge\mathbf{水博客警告}\]\(\mathfrak{T1}\石子游戏\)\(mad\)上来一个博弈论呼我脸上,这......
  • 将{"123","456"}集合转化为('123','456')
    需求分析优化接口时,需要手动拼接sql去调取神策的接口获取数据。好比将List<String>={"123","456"}集合转化为('123','456')。1publicclasstest3{23p......
  • endpoint is blank
    报错图 问题:简单来说使用nacos作为注册中心的时候并没有对注册中心进行配置而出现的报错   nacos注册中心采用bootstrap.yml或者bootstrap.properties文件进行......