过河(状压dp典型题)

xiaoxiao2021-02-28  111

这道题最简单的dp,动态转移方程很好推,因为它是由i-s~t转移来的,所以 动态转移方程为dp[i]=min(dp[i-s~t])+q[i] 然而这个题的数据太大了。。。。。10^9 不得不考虑一些没用的操作 所以就考虑一个问题 这个题的石子数太少了,在一定的范围内,你不管怎样跳,石子数也不会增加,所以你就可以把多余的t弄掉,这样就是状压dp了,把一定的没用的范围压起来,这样数据就小点了,能过了

#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> using namespace std; int n,m;int maxn=9999; int f[3000];int a[101];int q[3000];int d[101]; int ans=0;int l,s,t; int main() { scanf("%d",&l); scanf("%d%d%d",&s,&t,&m); for(int i=1;i<=m;i++){ scanf("%d",&a[i]); } sort(a+1,a+m+1); for(int i=1;i<=m;i++) if(a[i]-a[i-1]>t) d[i]=(a[i]-a[i-1])%t+t; else d[i]=a[i]-a[i-1]; for(int i=1;i<=m;i++) { a[i]=a[i-1]+d[i]; q[a[i]]=1; } for(int i=1;i<s;i++) f[i]=99999999; f[0]=0; for(int i=s;i<=a[m]+t;i++) {int w=99999; for(int j=s;j<=t;j++) { if(i-j>=0) w=min(f[i-j],w); } f[i]=w+q[i]; } for(int i=a[m];i<=a[m]+t;i++) maxn=min(maxn,f[i]); printf("%d ",maxn); return 0; }
转载请注明原文地址: https://www.6miu.com/read-18982.html

最新回复(0)