Ybt高效进阶 「CSP-J 2025 入门级模拟赛 Day1」最小步数

题目

赛时做法:记忆化搜索(90pts)

#include<bits/stdc++.h>
#include<bits/extc++.h>
using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
ifstream fin("steps.in");
ofstream fout("steps.out");
#define cin fin
#define cout fout
int n,a[103];
int mem[101][1000001];
int ms(int p,int t){
	if(t<0)return 998244353;
	if(p==n)return 1;
	if(mem[p][t])return mem[p][t];
	return mem[p][t]=min(ms(p+1,t+a[p+1])+1,ms(p+1,t-100));
}
int32_t main(){
	//ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	cin >> n;
	for(int i=1;i<=n;i++)cin >> a[i];
	cout << ms(0,0)-1;
}

使用了高达101*1000001的数组,然后就100→90了(悲)

正解:递推动态规划

#include<bits/stdc++.h>
#include<bits/extc++.h>
using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
int n,a[103],f[101][101],ans=-1;
const int INF=1e9;
ifstream fin("steps.in");
ofstream fout("steps.out");
#define cin fin
#define cout fout
int main(){
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	cin >> n;
	for(int i=1;i<=n;i++)cin >> a[i];
	fill((int*)f,(int*)f+(sizeof(f)/sizeof(int)),-INF);
	f[0][0]=0;
	for(int i=1;i<=n;i++)
		for(int j=0;j<=i;j++){
			f[i][j]=f[i-1][j]+a[i];
			if(j!=0)f[i][j]=max(f[i][j],f[i-1][j-1]-100);
			if(f[i][j]<0)f[i][j]=-INF;
		}
	for(int i=0;i<=n;i++)if(f[n][i]>=0)ans=n-i;
	cout << ans;
}
posted @ 2025-08-20 20:51  NotMonika  阅读(18)  评论(0)    收藏  举报