日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

洛谷1052——过河(DP+状态压缩)

發布時間:2023/12/10 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 洛谷1052——过河(DP+状态压缩) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目描述

在河上有一座獨木橋,一只青蛙想沿著獨木橋從河的一側跳到另一側。在橋上有一些石子,青蛙很討厭踩在這些石子上。由于橋的長度和青蛙一次跳過的距離都是正整數,我們可以把獨木橋上青蛙可能到達的點看成數軸上的一串整點:0,1,…,L0,1,…,L0,1,,L(其中LLL是橋的長度)。坐標為000的點表示橋的起點,坐標為LLL的點表示橋的終點。青蛙從橋的起點開始,不停的向終點方向跳躍。一次跳躍的距離是SSSTTT之間的任意正整數(包括S,TS,TS,T)。當青蛙跳到或跳過坐標為LLL的點時,就算青蛙已經跳出了獨木橋。

題目給出獨木橋的長度LLL,青蛙跳躍的距離范圍S,TS,TS,T,橋上石子的位置。你的任務是確定青蛙要想過河,最少需要踩到的石子數。

輸入輸出格式

輸入格式:

第一行有111個正整數L(1≤L≤109)L(1 \le L \le 10^9)L(1L109),表示獨木橋的長度。

第二行有333個正整數S,T,MS,T,MS,T,M,分別表示青蛙一次跳躍的最小距離,最大距離及橋上石子的個數,其中1≤S≤T≤101 \le S \le T \le 101ST10,1≤M≤1001 \le M \le 1001M100

第三行有MMM個不同的正整數分別表示這MMM個石子在數軸上的位置(數據保證橋的起點和終點處沒有石子)。所有相鄰的整數之間用一個空格隔開。

輸出格式:

一個整數,表示青蛙過河最少需要踩到的石子數。

輸入輸出樣例

輸入樣例#1:

10 2 3 5 2 3 5 6 7

輸出樣例#1:

2

說明

對于30%的數據,L≤10000L \le 10000L10000

對于全部的數據,L≤109L \le 10^9L109

2005提高組第二題

思路

如果不考慮數據范圍的話,可以很快得出遞推關系式:dp[i]=min(dp[i+k]+a[i])??(S≤k≤T)dp[i]=min(dp[i+k]+a[i])\ \ (S\leq k \leq T)dp[i]=min(dp[i+k]+a[i])??(SkT)a[i]a[i]a[i]iii點的石頭數dp[i]dp[i]dp[i]表示到達iii點踩到的最少石頭數)

然鵝看了數據范圍后,時間和空間都是過不去的。所以需要選擇別的方法:

  • S=TS=TS=T的時候,可以很容易得到:所有在SSS倍數位置上的點,都會走到,所以對該種情況進行特判

  • 我們可以發現石子在橋上放置的是非常稀疏的,而且當點的位置超過一定范圍,點都是可以跳到的。所以可以將石子所在的位置壓縮到這個范圍里去。將壓縮后位置儲存起來作為新的石頭的位置,按照這個位置進行dp即可

假設每次走ppp或者p+1p+1p+1步.我們知道gcd(p,p+1)=1gcd(p,p+1)=1gcd(p,p+1)=1.
由擴展歐幾里得可知,對于二元一次方程組:
px+(p+1)y=gcd(p,p+1)px+(p+1)y=gcd(p,p+1)px+(p+1)y=gcd(p,p+1)是有整數解的,即可得:px+(p+1)y=spx+(p+1)y=spx+(p+1)y=s是一定有整數解的。
px+(p+1)y=spx+(p+1)y=spx+(p+1)y=s的解為:x=x0+(p+1)t,y=y0?ptx=x_0+(p+1)t,y=y_0?ptx=x0?+(p+1)t,y=y0??pt。令0≤x≤p0\leq x\leq p0xp(通過增減tttp+1p+1p+1來實現),s>p×(p+1)?1s>p\times (p+1)?1s>p×(p+1)?1
則有:y=s?pxp+1≥s?p2p+1>p(p+1)?1?pxp+1≥0y=\dfrac {s-px}{p+1}\geq \dfrac {s-p^{2}}{p+1} >\dfrac {p\left( p+1\right) -1-px}{p+1}\geq 0y=p+1s?px?p+1s?p2?>p+1p(p+1)?1?px?0
即表示,當s≤p×(p+1)s\leq p\times (p+1)sp×(p+1)時,px+(p+1)y=spx+(p+1)y=spx+(p+1)y=s有兩個非負整數解,每次走ppp步或者p+1p+1p+1步,p×(p+1)p\times (p+1)p×(p+1)之后的地方均能夠到達。
如果兩個石子之間的距離大于p×(p+1)p\times (p+1)p×(p+1),那么就可以直接將他們之間的距離更改為p×(p+1)p \times (p+1)p×(p+1)
綜上,得到壓縮路徑的方法:若兩個石子之間的距離大于t×(t?1)t\times(t?1)t×(t?1),則將他們的距離更改為t×(t?1)t\times (t?1)t×(t?1)

為t≤10為t\leq10t10,因此我們可以直接將大于10×910\times910×9的距離直接化為909090.

關于路徑壓縮常數的選擇,證明過程詳見:https://blog.csdn.net/qq_34940287/article/details/77494073

AC代碼

/*************************************************************************> Author: WZY> School: HPU> Created Time: 2019-02-03 15:55:49************************************************************************/ #include <bits/stdc++.h> #define ll long long #define ull unsigned long long #define ms(a,b) memset(a,b,sizeof(a)) #define INF 0x7f7f7f7f const int maxn=1e6+10; const int mod=1e9+7; using namespace std; int a[maxn]; int dp[maxn]; int vis[maxn]; int main(int argc, char const *argv[]) {ios::sync_with_stdio(false);cin.tie(0);int L;int ans=0;int s,t,m;cin>>L;cin>>s>>t>>m;for(int i=1;i<=m;i++)cin>>a[i];if(s==t){for(int i=1;i<=m;i++){if(a[i]%s==0)ans++;}cout<<ans<<endl;return 0;}sort(a+1,a+1+m);int _=90;int res=a[1]%_;vis[res]=1;// 縮點for(int i=2;i<=m;i++){res+=(a[i]-a[i-1])%_;vis[res]=1;}for(int i=res;i>=0;i--){dp[i]=INF;for(int j=s;j<=t;j++)dp[i]=min(dp[i],dp[i+j]+vis[i]);}cout<<dp[0]<<endl;return 0; }

轉載于:https://www.cnblogs.com/Friends-A/p/11054978.html

總結

以上是生活随笔為你收集整理的洛谷1052——过河(DP+状态压缩)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。