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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【DP】剪草(jzoj 1510)

發(fā)布時間:2023/12/3 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【DP】剪草(jzoj 1510) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

剪草

題目大意:

有n棵小草,B某看它們很不順眼,想讓他們的高度總和不大于H,它們一開始各有一個高度,然后它們各有一個固定的生長值,B某每個單位時間可以將一棵草減掉(讓他的高度變?yōu)?),但小草每個單位時間會長一次,問B某在哪個時間可以讓小草總高度不大于H,如果永遠(yuǎn)不可能,那就輸出-1

數(shù)據(jù)范圍限制

1 ≤ N ≤ 50,0 ≤ H ≤ 1000000

0 ≤ h[i] ≤ 100000

1 ≤ grow[i] ≤ 100000

對于20%的數(shù)據(jù), 1 ≤ N ≤ 7。

提示

解題思路:

我們可以用f[i][j]來表示前i棵草減j次的最小高度,然后先枚舉結(jié)束時間(k),再枚舉第幾棵小草(i),再枚舉當(dāng)前時間(j),就得出下圖的公式,再套進(jìn)去算一下就可以了

f[i][j]=min{f[i?1][j]+a[i].g+a[i].grow?k不選f[i?1][j?1]+a[i].grow?(k?j)選f[i][j]=min\left\{\begin{matrix}f[i-1][j]+a[i].g+a[i].grow*k &不選\\ f[i-1][j-1]+a[i].grow*(k-j)&選\end{matrix}\right.f[i][j]=min{f[i?1][j]+a[i].g+a[i].grow?kf[i?1][j?1]+a[i].grow?(k?j)??

注釋:

不選的話就要加上他的高度,再生長k次,選的話就不加高度,但要算出接下來要生長的高度(k-j)

#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> using namespace std; int ans,n,h,f[55][55]; struct rec {int grow,g; }a[55]; bool cmp(rec x,rec y) {return x.grow<y.grow; } int main() {ans=-1;scanf("%d %d",&n,&h);for (int i=1;i<=n;++i)scanf("%d",&a[i].g);//輸入for (int i=1;i<=n;++i)scanf("%d",&a[i].grow);//輸入sort(a+1,a+1+n,cmp);//按生長速度從小到大排序for (int k=0;k<=n;++k){for (int i=1;i<=n;++i)for (int j=1;j<=i;++j)f[i][j]=2147483647;//預(yù)處理for (int i=1;i<=n;++i) f[i][0]=f[i-1][0]+a[i].g+a[i].grow*k;//處值for (int i=1;i<=n;++i)for (int j=1;j<=k;++j)f[i][j]=min(f[i-1][j]+a[i].g+a[i].grow*k,f[i-1][j-1]+a[i].grow*(k-j));//狀態(tài)轉(zhuǎn)移方程if (f[n][k]<=h)//判斷是否成立{ans=k;break;}}printf("%d",ans);//輸出return 0; }

總結(jié)

以上是生活随笔為你收集整理的【DP】剪草(jzoj 1510)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。