P4832 珈百璃堕落的开始
P4832 珈百璃堕落的开始
这是一道关于背包dp的题 通过这题也让我感受到了背包的多样化 以及关于背包容量和价值该如何选择
观察本题所给的元素分别为 sin^2 (x) cos^2 (x)
通过高中阶段的学习 我们可以发现: sin^2 (x) + cos^2 (x)=1
即若保证取到的数为整数,那么sin^2(x) 与 cos^2(x)必须为成对出现
那么我们要求的就是max(f(i)) 那么这个i是什么呢?
通过前面的分析可以得知 cnt(sin)=cnt(cos)
即一定有cnt(sin)-cnt(cos)=0
那么背包的容量就给定为cnt(sin)-cnt(cos)
目标:f(0)
由于cnt(sin)-cnt(cos)可能会出现负数导致数组越界
那么我们得给它加上一个数 H 使其下标不会越界
同时我们可以发现当前一组只会被上一组所影响
因此我们用0表示上一组,用1表示当前这一组
同时取和不取这个问题我们也得加以考虑
得到状态转移方程:
f_1(i)=max(f_1(i),max(f_0(i),f_0(i-w)+v)
代码如下:
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
const int H=1e6;
int n;
string s;
int f_0[H*2];
int f_1[H*2];
int cnt_s,cnt_c;
int l,r;
int main()
{
cin>>n;
memset(f_1,-0X3F,sizeof f_1);
memset(f_0,-0X3F,sizeof f_0);
f_0[H]=0;
rep(i,1,n)
{
cnt_s=cnt_c=0;
cin>>s;
int len=s.length()-1;
rep(j,0,len)
{
if(s[j]=='s')cnt_s++;
else if(s[j]=='c')cnt_c++;
}
int w=cnt_s-cnt_c;
l=min(l,l+w),r=max(r,r+w);
rep(j,l+H,r+H)
f_1[j]=max(f_1[j],max(f_0[j],f_0[j-w]+cnt_s));
rep(j,l+H,r+H)
f_0[j]=f_1[j];
}
cout<<f_1[H];
return 0;
}