【NOIP2005】过河(离散化后dp,升级版dp)
src: https://www.luogu.org/problemnew/show/P1052
输入数据不一定有序,排序一下~~~
因为L太大了,所以要把一段段没用的东西减掉,怎么减呢,这就是状压的另一种实现。
ac代码:
//#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<stdio.h> #include <cstdlib> #include<malloc.h> #include<algorithm> #include<functional> #include<utility> #include<cmath> #include<string.h> #include<string> #include<vector> #include<stack> #include<set> #include<queue> #include<list> //#include<bits/stdc++.h> using namespace std; int Max(int a, int b) { return a > b ? a : b; } int Min(int a, int b) { return a > b ? b : a; } #define FOR(i,a,b) for(int i=a;i<=b;i++) typedef long long LL; typedef unsigned long long ull; const int INF=99999999; const double eps = 1e-6; int n,s,t,m,p[1010],v[1010],dp[1010]; int main() { std::ios::sync_with_stdio(false); memset(v,0,sizeof(v)); cin>>n; cin>>s>>t>>m; FOR(i,1,m)cin>>p[i]; p[m+1]=n; sort(p,p+m+2); int cnt=0; FOR(i,1,m+1){ //cout<<(p[i]-p[i-1])%t<<endl;// if(p[i]-p[i-1]>=t){ cnt+=(p[i]-p[i-1])%t+t;//一定要+t,留有t个选择的余地 } else cnt+=p[i]-p[i-1]; v[cnt]=1; } //cout<<"cnt:"<<cnt<<endl;// FOR(i,0,cnt+t)dp[i]=INF;dp[0]=0; for(int i=1;i<=cnt-1+t;i++){ for(int j=s;j<=t;j++){ if(i-j<0)break; else {dp[i]=min(dp[i],dp[i-j]+v[i-j]);} } } int ans=INF; FOR(i,cnt,cnt-1+t)ans=min(ans,dp[i]); cout<<ans<<endl; return 0; }

浙公网安备 33010602011771号