珈百璃的堕落
题目描述
这道题是这样的:给定一些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
思路:
我们记一个式子的s和c的个数分别为a、b ,则不妨令体积v= a−b,那么答案就是体积为0时的最大价值w了。其实由对称性,也可以令所有v=b−a。那
于是就成了带有负数体积的背包问题 我们只需要处理一下数组下标越界的问题,因此我们把所有下标平移一个足够大的TT就可以了,其他照常写。另外由于有负数体积,直接滚动数组就会有后效性了,改为取膜滚动也无妨。方程:
dp[i][j+T] = max(dp[i][j+T], dp[i-1][j-v+T]+w)
dp[i][j+T]=max(dp[i][j+T],dp[i−1][j−v+T]+w)
#include<iostream>
#include<cstring>
#include<cstdio>
#define ll long long
using namespace std;
const int T =1000300;
int dp[2][2001005],n,ans,v[100001],l,r;
char a[50000001];
int main()
{
cin>>n;
memset(dp,0xcf,sizeof(dp));
dp[0][T]=0;
for(int i=1,len; i<=n; ++i)
{
scanf("%s",a);
len=strlen(a);
int vala=0,valb=0;
for(int j=0; j<len; j+=2)
{
if(a[j]=='c') vala++;
else valb++;
}
int w=vala,v=valb-vala;
l=min(l,l+v),r=max(r,r+v);
for(int j=l; j<=r; j++)
{
dp[i&1][j+T] = max(dp[i&1][j+T], dp[i&1^1][j+T]);
dp[i&1][j+T] = max(dp[i&1][j+T], dp[i&1^1][j-v+T]+w);
}
}
cout<<dp[n&1][T]<<endl;
}