洛谷9.23

[IOI2000] 回文字串

题目背景

IOI2000 第一题

题目描述

回文词是一种对称的字符串。任意给定一个字符串,通过插入若干字符,都可以变成回文词。此题的任务是,求出将给定字符串变成回文词所需要插入的最少字符数。

比如 Ab3bd \verb!Ab3bd! Ab3bd 插入 2 2 2 个字符后可以变成回文词 dAb3bAd \verb!dAb3bAd! dAb3bAd 或 Adb3bdA \verb!Adb3bdA! Adb3bdA,但是插入少于 2 2 2 个的字符无法变成回文词。

注意:此问题区分大小写。

输入格式

输入共一行,一个字符串。

输出格式

有且只有一个整数,即最少插入字符数。

样例 #1

样例输入 #1

Ab3bd

样例输出 #1

2

提示

数据范围及约定

记字符串长度为 l l l。

对于全部数据, 0 < l ≤ 1000 0<l\le 1000 0<l≤1000。

分析

令 d p [ i ] [ j ] dp[i][j] dp[i][j]表示使坐标从j到i的子串变成回文串所需要的最小字符数,当 s [ i ] = = s [ j ] s[i]==s[j] s[i]==s[j]时,此时可以选择添加,此时需要下表从 i i i到 j + 1 j+1 j+1为回文串,则 d p [ i ] [ j ] = d p [ i ] [ j + 1 ] + 1 dp[i][j]=dp[i][j+1]+1 dp[i][j]=dp[i][j+1]+1,或者不添加,则 d p [ i ] [ j ] = d p [ i − 1 ] [ j + 1 ] dp[i][j]=dp[i-1][j+1] dp[i][j]=dp[i−1][j+1],当 s [ i ] ! = s [ j ] s[i]!=s[j] s[i]!=s[j]时,可以选择在 i i i和 j j j处添加,若在 i i i处添加,此时下标 j + 1 j+1 j+1到 i i i得是回文串,则 d p [ i ] [ j ] = d p [ i ] [ j + 1 ] + 1 dp[i][j]=dp[i][j+1]+1 dp[i][j]=dp[i][j+1]+1,同理在 j j j处添加,则 d p [ i ] [ j ] = d p [ i − 1 ] [ j ] + 1 dp[i][j]=dp[i-1][j]+1 dp[i][j]=dp[i−1][j]+1,最后取最小的即可。

代码

c 复制代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1005, INF = 0x3f3f3f3f;
int dp[N][N];
int main() {
    string s;
    cin >> s;
    int n = s.size();
    for(int i = 1; i <= n; i ++ ) {
        for(int j = i; j >= 1; j -- ) {
            if(s[j - 1] == s[i - 1]) {
                dp[i][j] = min(dp[i][j + 1] + 1, dp[i - 1][j + 1]);
            } else {
                dp[i][j] = min(dp[i - 1][j], dp[i][j + 1]) + 1;
            }
        }
    }
    cout << dp[n][1];
    return 0;
}

[USACO03FALL] Cow Exhibition G

题目背景

题目描述

奶牛想证明它们是聪明而风趣的。为此,贝西筹备了一个奶牛博览会,她已经对 N N N 头奶牛进行了面试,确定了每头奶牛的智商和情商。

贝西有权选择让哪些奶牛参加展览。由于负的智商或情商会造成负面效果,所以贝西不希望出展奶牛的智商之和小于零,或情商之和小于零。满足这两个条件下,她希望出展奶牛的智商与情商之和越大越好,请帮助贝西求出这个最大值。

输入格式

第一行:单个整数 N N N, 1 ≤ N ≤ 400 1 \le N \le 400 1≤N≤400。

第二行到第 N + 1 N+1 N+1 行:第 i + 1 i+1 i+1 行有两个整数: S i S_i Si 和 F i F_i Fi,表示第 i i i 头奶牛的智商和情商,− 1000 ≤ S i ; F i ≤ 1000 1000 \le S_i;F_i \le 1000 1000≤Si;Fi≤1000。

输出格式

输出单个整数:表示情商与智商和的最大值。贝西可以不让任何奶牛参加展览,如果这样做是最好的,输出 0 0 0。

样例 #1

样例输入 #1

5
-5 7
8 -6
6 -3
2 1
-8 -5

样例输出 #1

8

提示

选择第一头,第三头,第四头奶牛,智商和为−5+6+2 = 3,情商和为7−3+1 = 5。再加

入第二号奶牛可使总和提升到10,不过由于情商和变成负的了,所以是不允许的

分析

可以看出这是01背包的变式,令dp[i][j]表示取前i个奶牛,总智商为j的情商的最大值,最后答案只需要遍历所有的dp,获取情商和智商和即可。同普通01背包,状态转移如下

  • dp[i][j]=max(dp[i-1][j],dp[i-1][j-w]+v)

但是这里会出现智商为负的情况,导致数组越界,因此可以将dp数组整体右移4e5个单位,最后二维会MLE,需要滚动数组优化一下,还有一个重点,优化成一维时,若体积为负,则可能超过最大体积,此时需要正着遍历

代码

c 复制代码
#include<bits/stdc++.h>
using namespace std;
const int N = 405, M = 9e5 + 5;
int dp[M]; // dp[i][j] 取i个奶牛,总智商为j,情商的最大值
struct node_ {
    int first, second;
}t[N];
int main() {
    int n;
    cin >> n;
    int maxn = 0;
    memset(dp, -0x3f, sizeof(dp));
    dp[(int)4e5] = 0;
    for(int i = 1; i <= n; i ++ ) {
        cin >> t[i].first >> t[i].second;
        maxn += t[i].first > 0 ? t[i].first : 0;
    }
    for(int i = 1; i <= n; i ++ ) {
        if(t[i].first >= 0) {
            for(int j = 8e5; j >= t[i].first; j -- ) dp[j] = max(dp[j], dp[j - t[i].first] + t[i].second);
        } else {
            for(int j = 0; j <= 8e5 + t[i].first; j ++ ) dp[j] = max(dp[j], dp[j - t[i].first] + t[i].second);
        }
    }
    int res = 0;
    for(int i = 4e5; i <= 8e5; i ++ ) {
        if(dp[i] > 0)
            res = max(res, dp[i] + i - (int)4e5);
    }
    cout << res << endl;
    return 0;
}
相关推荐
从以前24 分钟前
【算法题解】Bindian 山丘信号问题(E. Bindian Signaling)
开发语言·python·算法
不白兰28 分钟前
[代码随想录23回溯]回溯的组合问题+分割子串
算法
御风@户外1 小时前
质数生成函数、质数判断备份
算法·acm
闻缺陷则喜何志丹1 小时前
【C++动态规划】1105. 填充书架|2104
c++·算法·动态规划·力扣·高度·最小·书架
Dong雨2 小时前
六大排序算法:插入排序、希尔排序、选择排序、冒泡排序、堆排序、快速排序
数据结构·算法·排序算法
达帮主2 小时前
7.C语言 宏(Macro) 宏定义,宏函数
linux·c语言·算法
是十一月末2 小时前
机器学习之KNN算法预测数据和数据可视化
人工智能·python·算法·机器学习·信息可视化
chenziang12 小时前
leetcode hot100 路径总和
算法
lyx1426062 小时前
leetcode 3083. 字符串及其反转中是否存在同一子字符串
算法·leetcode·职场和发展
茶猫_2 小时前
力扣面试题 39 - 三步问题 C语言解法
c语言·数据结构·算法·leetcode·职场和发展