20251224DP小测错因

A P1802 5 倍经验日

赛时代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
long long dp[1005];
int main(){
	int n,x;
	cin>>n>>x;
	for(int i=1;i<=n;i++){
		int l,w,u;
		cin>>l>>w>>u;
		for(int j=x;j>=1;j--){//没有枚举到0
			dp[j]=max(dp[j],dp[j]+l);
			if(j>=u){
				dp[j]=max(dp[j],dp[j-u]+w);
			}
		}
	}
	cout<<dp[x]*5;
	return 0;
}

改后代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
long long dp[1005];
int main(){
	int n,x;
	cin>>n>>x;
	for(int i=1;i<=n;i++){
		int l,w,u;
		cin>>l>>w>>u;
		for(int j=x;j>=0;j--){
			if(j>=u){
				dp[j]=max(dp[j]+l,dp[j-u]+w);
			}else{
				dp[j]+=l; 
			}
		}
	}
	cout<<dp[x]*5;
	return 0;
}

挂了70分。

B B4177 [BCSP-X 2024 6 月初中组] 尽量接近

赛时代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
bool dp[1000005];
int main(){
	dp[0]=1;
	int n,k,sum=0;
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		int x;
		cin>>x;
		sum+=x;
		for(int j=sum;j>=x;j--){
			dp[j]|=dp[j-x];
		}
	}
	int mn=INT_MAX;
	bool cc=0;
	for(int i=k*2;i>=0;i--){
		if(dp[i]){
			if(abs(k-i)<mn){
				mn=abs(k-i);
				if(i>k){
					cc=1;
				}
			}
		}
	}
	if(cc){
		cout<<mn+k;
	}else{
		cout<<mn-k;
	}
	return 0;
}

本来用的精卫填海的思路,后来发现写错了,于是就仿照kkksc03临时抱佛脚来写,于是A了。

改后代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;//隐藏了两位巨佬的名字
int a[55];
int dp[1000005],n,k,sum=0;
int ggy(int lyz){//因为两次背包,所以用函数包装
	memset(dp,0,sizeof dp);
	for(int i=1;i<=n;i++){//01背包
		for(int j=lyz;j>=a[i];j--){//枚举背包容量
			dp[j]=max(dp[j],dp[j-a[i]]+a[i]);
		}
	}
	return dp[lyz];
}
int main(){
	dp[0]=1;
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		int x;
		cin>>a[i];
		sum+=a[i];
	}
	if(sum<=k){
		cout<<sum;
		return 0;
	}
	int x1=ggy(k);//容量为k
	int x2=sum-ggy(sum-k);//容量为sum-k,最后答案要用sum减去
	if(k-x1<=x2-k){//如果第一个答案比第一个答案跟接近k,相同时选更小的
		cout<<x1;
	}else{
		cout<<x2;
	}
	return 0;
}

挂了80分。

C P13015 [GESP202506 六级] 学习小组

为什么有一个人没有A呢,好 难 猜 啊 ~

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int a[1005],dp[1005];
int main(){
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	for(int i=1;i<=n;i++){//枚举物品,重量为i,价值为a[i]
		for(int j=i;j<=n;j++){//完全背包
			dp[j]=max(dp[j],dp[j-i]+a[i]);
		}
	}
	cout<<dp[n];
	return 0;
}

D P8816 [CSP-J 2022] 上升点列

40分是骗的,不要以为我想到了正解......

骗分代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
struct node{
	int x,y;
}a[505];
bool cmp(node x,node y){
	if(x.x==y.x){
		return x.y<y.y;
	}
	return x.x<y.x;
}
int dp[505];
bool check(int x,int y){
	if(a[x].x==a[y].x&&a[x].y+1==a[y].y)return 1;
	if(a[x].x+1==a[y].x&&a[x].y==a[y].y)return 1;
	return 0;
}
int main(){
	int n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>a[i].x>>a[i].y;
	}
	sort(a+1,a+1+n,cmp);
	int mx=0;
	for(int i=1;i<=n;i++){
		dp[i]=1;
		for(int j=1;j<i;j++){
			if(check(j,i)){
				dp[i]=max(dp[i],dp[j]+1);
			}
		}
		mx=max(mx,dp[i]);
	}
	cout<<mx;
	return 0;
}

杨老师的原话:"这道题没有人能拿到"然后顿了一下,"40分以上。"

题意:给定n个点,允许添加k个点,使得所有点的x和y都是正整数,且选出的点的序列构成一条最长的折线,x和y单调不减。

因为序列中相邻两点的关系只有两种,要么在下面,要么在左边,所以对于点 i 和点 j ,中间需要添加的点数=max(0,|a[i].x-a[j].x|+|a[i].y-a[j].y|)

状态:dp[i][j]表示以第 i 个点为结尾已经添加 j 个点的最大长度。

答案:max(dp[i][k])

初始状态:dp[i][j]=j+1

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
struct node{
	int x,y;
}a[505];
bool cmp(node x,node y){
	if(x.x==y.x){
		return x.y<y.y;
	}
	return x.x<y.x;
}
int dp[505][505];
int check(int x,int y){//计算这两点之间最少要加几个点才能相连
	if(x==y)return 0;//同一点返回0就行了
	return abs(a[x].x-a[y].x)+abs(a[x].y-a[y].y)-1;
}
int main(){
	int n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>a[i].x>>a[i].y;
	}
	sort(a+1,a+1+n,cmp);//这里提到了排序,说明DP和贪心息息相关
	for(int i=1;i<=n;i++){
		for(int j=0;j<=k;j++){
			dp[i][j]=j+1;//加j个点再算上i点,就是j+1个点
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=0;j<=k;j++){
			for(int p=1;p<=i;p++){
				if(p==i){
					dp[i][j]=max(dp[i][j],dp[p][j-1]+1);
				}
				int x=check(i,p);
				if(p<i&&x<=j&&a[p].y<=a[i].y){
					dp[i][j]=max(dp[i][j],dp[p][j-x]+x+1);
				}
			}
		}
	}
	int ans=0;
	for(int i=1;i<=n;i++){
		ans=max(ans,dp[i][k]); 
	}
	cout<<ans;
	return 0;
}
相关推荐
LYFlied17 小时前
【每日算法】LeetCode 64. 最小路径和(多维动态规划)
数据结构·算法·leetcode·动态规划
Yzzz-F18 小时前
算法竞赛进阶指南 动态规划 背包
算法·动态规划
leaves falling21 小时前
动态规划讲解
算法·动态规划
LYFlied1 天前
【每日算法】LeetCode 279. 完全平方数(动态规划)
前端·算法·leetcode·面试·动态规划
scx201310041 天前
20251201换根DP总结
算法·动态规划·换根dp
元亓亓亓1 天前
LeetCode--279. 完全平方数--中等
算法·leetcode·动态规划
山楂树の2 天前
爬楼梯(动态规划)
算法·动态规划
资生算法程序员_畅想家_剑魔2 天前
算法-动态规划-13
算法·动态规划
xiaoxue..2 天前
爬楼梯问题:从递归到动态规划再到闭包的进化之路
javascript·算法·面试·动态规划