洛谷 P4832 珈百璃堕落的开始

题目背景

“恭喜你,珈百璃,你以学年首席的优秀成绩毕业”

珈百璃,一位优秀的天使,今天她以学年首席的成绩毕业,从今往后,她将前往人间进行进一步修炼。

“我会努力给人类带来幸福的!”珈百璃憧憬着人间生活

开学第一天,珈百璃就凭借着他及其可爱的外表,受到了班级成员的追捧,不仅长得可爱,成绩还很优秀,简直就是女神啊!

因为她的成绩优秀,所以她的作业也是很快就快要完成了,但是就在她快完成数学作业时,她的电脑传来了呼救的声音“救命啊!”

顺着这个呼救声,珈百璃望向了电脑。“原来是游戏啊”珈百璃看着屏幕里一位倒在地上的残血战士,注册了账号,选择了牧师职业,对这位战士进行了救治。在珈百璃开心的同时,越来越多的呼救声传来,珈百璃一个一个进行救治,但她的level才1,mp肯定不足,当她想要继续进行救治的时候,系统提示mp不足并给出了氪金的提示“屠龙宝刀,点击就送”

“生活费天界学院倒是有给,但是。。。。”珈百璃看着自己的存折,再看看屏幕,她纠结不已

“救命啊!!!”“救。。救命啊。。。”“救命啊!!!”珈百璃看着这些人一个个喊出救命,自己却无能为力,终于,她控制不住自己,点下了‘氪金’按钮。

从此,珈百璃的堕落就开始了,她的作业,也停在了这道数学题上。。。。。。

“薇奈特,帮我写一下作业嘛”珈百璃央求着薇奈特

“真是的,你好歹也是天使呢,也该自己做一点作业吧”

“不要,我还要打游戏呢”

“这怎么行,你是天使啊”

“我已经决定做一位成天打游戏不学习的堕天使了”

“真是服了你啊,那你好好打游戏吧,我帮你写”

题目描述

这道题是这样的:给定一些sin(x)^2,cos(x)^2(x=pi/7)组成的式子,请你帮忙求出选择一些式子相加后得到的最大整数答案

输入格式

第一行一个整数n,表示n个式子

接下来n行每行一个字符串,由f(i)=sin(x)^2,cos(x)^2 和+组成(x=pi/7) ,为了简化输入,我们以s代表sin(x)^2 ,以c代表cos(x)^2 ,并省略f(i)=

输出格式

一个数表示最大整数答案,计算全部为加法

输入输出样例

输入 #1
3
s+c
s+c+s
c
输出 #1
3

说明/提示

样例解释:三个式子都选,则加起来等于3

设s和c的个数总和为m

10%的数据n=1

另有20%的数据每行一个单项式

另有20%的数据n≤20

100%的数据nm≤5*10^7,m≤10^6

 

原网址:https://www.luogu.com.cn/problem/P4832

 

思路:一开始看到之后,想用两个状态表示s和c的个数,但是m可能很大,所以放弃了,然后就想着反正是要两个字母的个数相等,那能不能直接以字母的差为状态。

这样就不难发现其实就是一个变换了状态的背包,我们用s[i]表示第i个式子s的个数,c[i]表示第i个式子c的个数,两个数减一减视为重量,减数视作价值,那么答案就是重量和为零时的dp值

 

式子就是简单的背包转移式,注意因为重量会变负数所以加一个大数,然后加上滚动即可。

下附代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 using namespace std;
 5 const int T = 1000300;
 6 const int INF=0X3f3f3f3f;
 7 int dp[2][2*T];
 8 int l,r,n;
 9 char s[2000005];
10 struct node{
11     int s,c,w,v;
12 }a[2000005];
13 int main(){
14     memset(dp,-INF,sizeof(dp));
15     scanf("%d",&n);
16     for (int i=1; i<=n; i++){
17         scanf("%s",s);
18         int l=strlen(s);
19         for (int j=0; j<l; j+=2){
20             if (s[j]=='s') a[i].s++;
21             if (s[j]=='c') a[i].c++;
22             a[i].w=a[i].s-a[i].c;
23             a[i].v=a[i].c;
24         }
25     }
26     dp[0][T]=0;
27     for (int i=1; i<=n; i++){
28         l=min(l,l+a[i].w),r=max(r,r+a[i].w);
29         for (int j=l; j<=r; j++){
30             dp[i&1][j+T]=max(dp[i&1][j+T],dp[(i&1)^1][j+T]);
31             dp[i&1][j+T]=max(dp[i&1][j+T],dp[(i&1)^1][j-a[i].w+T]+a[i].v);
32         }
33     }
34     printf("%d\n",dp[n&1][T]);
35 }
View Code

 

posted @ 2020-10-01 21:10  我是菜狗QAQ  阅读(220)  评论(0编辑  收藏  举报