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;
} 
posted @ 2024-04-15 22:15  0tAp  阅读(9)  评论(0编辑  收藏  举报