洛谷刷题6.18&&6.17

 P1855 榨取kkksc03 - 洛谷

简单的二维01背包

#include<bits/stdc++.h>
#define ll long long
#define N 1005
using namespace std;
int t,a,b,dp[205][205],n,m;
int main()
{
cin>>t>>n>>m;
while(t--){
	cin>>a>>b;
	for(int i=n;i>=a;i--){
		for(int j=m;j>=b;j--){
			dp[i][j]=max(dp[i][j],dp[i-a][j-b]+1);
		}
	}
}
cout<<dp[n][m];
	return 0;
}

P1833 樱花 - 洛谷

混合背包问题,分类即可

#include<bits/stdc++.h>
#define ll long long
#define N 1005
using namespace std;
int n,a,b,c,d,t,dp[1005];
char ch;
int main()
{
cin>>a>>ch>>b>>c>>ch>>d>>t;
n=c*60+d-a*60-b;
while(t--){
	cin>>a>>b>>c;
	if(c==0){
		for(int i=a;i<=n;i++){
			dp[i]=max(dp[i],dp[i-a]+b);
		}
	}
	else{
		for(int j=1;j<=c;j++){
			for(int i=n;i>=a;i--){
				dp[i]=max(dp[i],dp[i-a]+b);
			}
		}
	}
}
cout<<dp[n];
	return 0;
}

P1203 [USACO1.1] 坏掉的项链 Broken Necklace - 洛谷

模拟题,细节惊人

1.如果断开的地方开头是白色珠子,如何处理?

2.如果全是白色珠子的情况。

#include<bits/stdc++.h>
using namespace std;
string s;
int n,ans;
void suan(int l,int r){
	int sum=0;
	while(s[l]=='w'&&l<r){
		l++;
		sum++;
	}
	while(s[r]=='w'&&r>l){
		r--;
		sum++;
	}
	if(r==l+1){
		ans=max(ans,sum);
		return;
	} 
	char left=s[l],right=s[r];
	for(;l<=r;l++){
		if(s[l]!=left&&s[l]!='w'){
			l--;
			break;
		}
		else{
			sum++;
		}
	}
	for(;r>l;r--){
		if(s[r]!=right&&s[r]!='w') break;
		else sum++;
	}
	ans=max(ans,sum);
}
int main()
{
cin>>n>>s;
if(n==1){
	cout<<1;
	return 0;
} 
s=s+s;
for(int i=0;i<n;i++){
	suan(i,i+n-1);
}
cout<<ans;
	return 0;
}

P1103 书本整理 - 洛谷

先按高度排序书籍。

令 m = n - m(m 表示保留的书数)。

定义 dp[i][j] 表示以第 i 本书为最后一本,且总共选择 j 本书(包括 i)时的最小不整齐度。

初始化 dp[i][1] = 0(只选一本书时,不整齐度为 0)。

三重循环更新 dp:

i 从 1 到 n(当前书)。

j 从 1 到 i-1(前一本书)。

k 从 1 到 min(j, m-1)(j 之前已选 k 本书)。

状态转移:dp[i][k+1] = min(dp[i][k+1], dp[j][k] + abs(arr[i].w - arr[j].w))。

最后取 min(dp[i][m]) 作为答案。
还有个小细节请看https://www.luogu.com.cn/discuss/1093824,是关于0x3f的坑

#include<bits/stdc++.h>
using namespace std;
struct book{
	int h,w;
}arr[105]; 
int n,m,dp[105][105];
bool cmp(book &s1,book &s2){
	return s1.h<s2.h;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++){
	cin>>arr[i].h>>arr[i].w;
}
sort(arr+1,arr+1+n,cmp);
m=n-m;
memset(dp,0x3f,sizeof(dp));
for(int i=1;i<=n;i++){
	dp[i][1]=0;
	for(int j=1;j<i;j++){
		for(int k=1;k<=min(j,m-1);k++){
			dp[i][k+1]=min(dp[i][k+1],dp[j][k]+abs(arr[i].w-arr[j].w));
		}
	}
}
int ans=0x3f3f3f;
for(int i=1;i<=n;i++){
	ans=min(ans,dp[i][m]);
}
cout<<ans;
	return 0;
}

P5365 [SNOI2017] 英雄联盟 - 洛谷

多重背包,注意循环遍历的次序,先是遍历物品,再体积,再是件数。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct point{
	ll k,c;
}arr[10000];
ll n,m,dp[300005],sum;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++){
	cin>>arr[i].k;
}
for(int i=1;i<=n;i++){
	cin>>arr[i].c;
	sum+=arr[i].c*arr[i].k;
}
dp[0]=1;
for(ll i=1;i<=n;i++){
	for(ll j=sum;j>=0;j--){
		for(int k=1;k<=arr[i].k&&k*arr[i].c<=j;k++){
			dp[j]=max(dp[j],dp[j-k*arr[i].c]*k);
		}
	}
}
for(ll i=1;i<=sum;i++){
	if(dp[i]>=m){
		cout<<i;
		break;
	}
}
	return 0;
}

P4141 消失之物 - 洛谷

去掉一个物品就是逆操作,注意遍历的顺序。还有要不断取模,数会很大。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,m,arr[2005],dp[2005],ans[2005];
int main()
{
cin>>n>>m;
dp[0]=1;
for(int i=1;i<=n;i++){
	cin>>arr[i];
	for(int j=m;j>=arr[i];j--){
		dp[j]+=dp[j-arr[i]];
		dp[j]%=10;
	}
}
for(int i=1;i<=n;i++){
	memcpy(ans,dp,sizeof(dp));
	for(int j=arr[i];j<=m;j++){
		ans[j]=(ans[j]-ans[j-arr[i]]+10)%10;
	}
	for(int j=1;j<=m;j++){
		cout<<ans[j]%10;
	}
	cout<<endl;
}
	return 0;
}

P1541 [NOIP 2010 提高组] 乌龟棋 - 洛谷

此题更像是递推。以四种棋的数目为下标,确定每种组合的状态。记忆化搜索也可。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,m,v[355],dp[41][41][41][41],num[5],a;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++){
	cin>>v[i];
}
while(m--){
	cin>>a;
	num[a]++;
}
dp[0][0][0][0]=v[1];
for(int i=0;i<=num[1];i++){
	for(int j=0;j<=num[2];j++){
		for(int k=0;k<=num[3];k++){
			for(int p=0;p<=num[4];p++){
				int now=1+i+j*2+k*3+4*p;
				if(i!=0) dp[i][j][k][p]=max(dp[i][j][k][p],dp[i-1][j][k][p]+v[now]);
				if(j!=0) dp[i][j][k][p]=max(dp[i][j][k][p],dp[i][j-1][k][p]+v[now]);
				if(k!=0) dp[i][j][k][p]=max(dp[i][j][k][p],dp[i][j][k-1][p]+v[now]);
				if(p!=0) dp[i][j][k][p]=max(dp[i][j][k][p],dp[i][j][k][p-1]+v[now]);
			}			
		}
	}
}
cout<<dp[num[1]][num[2]][num[3]][num[4]];
	return 0;
}

P1168 中位数 - 洛谷

此题博主用了奇巧淫技vector,二分查找+插入可让vector爆发出接近树形结构的性能。只是针对数据不强,如果数据特殊设计过就没法过。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
vector<ll>arr;
int main()
{
ll n,a;
scanf("%lld",&n);
for(int i=1;i<=n;i++){
	scanf("%lld",&a);
	arr.insert(lower_bound(arr.begin(),arr.end(),a),a);
	if(i%2==1){
		printf("%lld\n",arr[i/2]);
	}
}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值