Loppinha, the boy who likes sopinha Gym - 101875E (dp,记忆化搜索)

https://vjudge.net/contest/299302#problem/E

题意:给出一个01 0101串,然后能量计算是连续的1就按1, 2, 3的能量加起来。然后给出起始的能量,求最少减掉几个一是起始的能量不被消耗完。

思路:不能用贪心,比如11111,按理说拿一个最好是中间分开,但是那两次的这种情况下应该是要把第二个和第四个拿掉来最小

所以要用记忆化搜索或dp;

记忆化搜索

#include<bits/stdc++.h>

using namespace std;

const int maxn = 505;
const int inf = 1e9 + 7;
int dp[maxn][maxn];////dp[i][j]表示处理了前i个数字,然后还可以换j次,i个数字后还所需要消耗的能量
char ch[maxn];
int n, m;

int cal(int x) {
    return x * (x + 1) / 2;
}
//递归边界是刚好处理完n个数字,并且要求k>=0
int dfs(int p, int k) {//前p个数字,换k次
    if(k < 0) return inf;
    if(p >= n) return 0;//注意这两句不能换位置!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    if(dp[p][k] != -1) return dp[p][k];
    if(ch[p] == ‘0‘) return dfs(p + 1, k);//为0就肯定不用换,继续递归
    dp[p][k] = inf;//先初始化为INF
    int i;
    for(i = p; i < n && ch[i] == ‘1‘; i++) {//当有一个位置为0的时候跳出循环
        dp[p][k] = min(dp[p][k], dfs(i + 1, k - 1) + cal(i - p));//考虑将第i个1换成0
    }
    dp[p][k] = min(dp[p][k], dfs(i + 1, k) + cal(i - p));//第i位置是0
    return dp[p][k];
}

int main() {
scanf("%d%d", &n, &m);
scanf("%s", ch);
memset(dp, -1, sizeof(dp));
for(int i = 0; i <= n; i++) {
    if(dfs(0, i) <= m) {
        printf("%d\n", i);
        return 0;
    }
}
return 0;
}

原文地址:https://www.cnblogs.com/downrainsun/p/10806997.html

时间: 2024-10-10 09:09:05

Loppinha, the boy who likes sopinha Gym - 101875E (dp,记忆化搜索)的相关文章

【每日dp】 Gym - 101889E Enigma 数位dp 记忆化搜索

题意:给你一个长度为1000的串以及一个数n 让你将串中的'?'填上数字 使得该串是n的倍数而且最小(没有前导零) 题解:dp,令dp[len][mod]为是否出现过 填到第len位,余数为mod 的状态(dp=0 or 1) 用记忆化搜索来实现,dfs返回1或0. 如果搜到最后一位并且余数为0,返回1. 如果搜到已经更新过的dp状态,直接返回0. 将mod作为全局变量,不断更新mod. 对于每一位 的'? ' 暴力枚举0~9 #include<stdio.h> #include<std

GYM 101933E(记忆化搜索)

用每个人的血量作为状态去搜索T飞,考虑题解中更好的搜索方式:每种血量有多少个人作为状态.这样会减去很多重复的状态,因为只要乘一下就得到了所有相同情况的和. 虽然我不会算,但是直观感受起来复杂度比较优秀. #include <cstdio> #include <unordered_map> using namespace std; typedef double db; typedef long long ll; int n, m, d, mod = 1e6; int cnt[2][1

Gym 100650H Two Ends DFS+记忆化搜索

Problem H: Two EndsIn the two-player game “Two Ends”, an even number of cards is laid out in a row. On each card, faceup, is written a positive integer. Players take turns removing a card from either end of the row andplacing the card in their pile.

Gym 101334E dp

分析: 这一题给出的遍历的点的序列,不是树的中序遍历,前序遍历,只要遇到一个节点就打印一个节点.关键点就在,这个序列的首字母和尾字母一定要相同,因为最终都会回到根节点,那么每一个子树也一样. 状态: d[i][j]表示i至j的状态数 d[i][j]= d[i][j]=(d[i][j]+dp(i,k)*dp(k+1,j-1)%mod)%mod; #include <bits/stdc++.h> using namespace std; typedef long long ll; const in

Gym 101142C CodeCoder vs TopForces (搜索)

题意:每个人有2种排名,对于A只要有一种排名高于B,那么A就能赢B,再如果B能赢C,那么A也能赢C,要求输出每个人分别能赢多少个人 析:首先把题意先读对了,然后我们可以建立一个图,先按第一种排名排序,然后从高的向向低的连一条边,然后再按第二种排序,同理连线. 最后dfs一次,要先从排名低的开始遍历,不用清0,因为是从排名低的开始的.也可以用强连通分量或者线段树. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000")

Gym 101334D 记忆化dp

大致题意: 给你9堆扑克牌,每堆牌有4张,大小从A~K.每次从9堆牌牌顶抽走两张大小相同的牌,且抽走每一对相同的牌的概率都相等.问可以全部抽完的概率. 分析: 这是一道概率dp题.剩余的牌数作为状态,有9堆,意味着要一个9维数组来存d[i1][i2][i3][i4][i5][i6][i7][i8][i9]表示这个状态的概率,0<=i<=4. 状态转移: 当前状态的概率等于抽走两张牌后所能达到的状态的概率和除以所能达到的状态数 边界d[0][0][0][0][0][0][0][0][0]=1 #

Gym - 101889E Enigma(数位填数+记忆化)

https://cn.vjudge.net/problem/Gym-101889E 1??????????????????????????????? 2 10000000000000000000000000000000 ???????????????????????????????1 2 * ?294?? 17 129404 题意:给出一个数(长度<=1000),某些数位未知,向?填数,使其能被MOD(<=1000)整除且最小(不含前导零). 利用数位dp思想,从前往后从小到大依次填数,dp[

URAL 1501 Sense of Beauty

1501. Sense of Beauty Time limit: 0.5 second Memory limit: 64 MB The owner of a casino for New Russians has a very refined sense of beauty. For example, after a game there remain two piles with the same number of cards on the table, and the owner lik

(寒假开黑gym)2018 ACM-ICPC, Syrian Collegiate Programming Contest

layout: post title: (寒假开黑gym)2018 ACM-ICPC, Syrian Collegiate Programming Contest author: "luowentaoaa" catalog: true tags: mathjax: true - codeforces 传送门 付队! 许老师! Hello SCPC 2018! (签到) #include<bits/stdc++.h> using namespace std; typedef