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;
}