1 条题解
-
1
一开始,我试图通过贪心策略确定每次带奶牛的最大数量(maxx),然后固定每次带maxx头奶牛过河。
也就是
#include<bits/stdc++.h> using namespace std; int n,m,mi,a[2501],maxx,t; bool b; int main(){ cin>>n>>m; a[0]=m; for(int i=1;i<=n;i++){ cin>>mi; a[i]=a[i-1]+mi; if(a[i]>(a[i-1]+a[1]+m)&&b==0){ b=1; maxx=i-1; } } if(b==0){ maxx=n; } while(n>0){ if(n>=maxx){ t+=a[maxx]; n-=maxx; } else{ t+=a[n]; n=0; } if(n!=0){ t+=m; } } cout<<t; return 0; }但是这种方法在某些情况下可能不是最优的,因为它只考虑了带i头奶牛与带i-1头和1头奶牛的对比,而没有考虑其他分配方式(例如带2头和2头可能比带3头和1头更优)。因此,此代码在特定数据下可能无法得到最短时间。
所以为了解决这个问题,建议使用动态规划(DP)方法。DP方法通过计算所有可能的分段方式,确保找到最短总时间。具体步骤如下:
1.读取奶牛数量n和独自渡河时间m。
2.计算数组a,其中a[i]表示带i头奶牛过河所需的时间(包括基础时间m和额外时间)。
3.初始化DP数组dp,其中dp[i]表示带i头奶牛过河的最短总时间,初始时dp[0] = 0。
4.对于每个i从1到n,遍历所有可能的j(1到i),计算dp[i] = min(dp[i], dp[i-j] + a[j] + (i-j > 0 ? m : 0))。这表示将i头奶牛分为先带i-j头再带j头,其中如果i-j>0则需要返回时间m。
5.输出dp[n]。
也就是
#include<bits/stdc++.h> using namespace std; int main(){ int n,m; cin>>n>>m; int a[n+1]; a[0]=m; for(int i=1;i<=n;i++){ int mi; cin>>mi; a[i]=a[i-1]+mi; } int dp[n+1]; dp[0]=0; for(int i=1;i<=n;i++){ dp[i]=1e9; for(int j=1;j<=i;j++){ if(i-j>0){ dp[i]=min(dp[i],dp[i-j]+a[j]+m); }else{ dp[i]=min(dp[i],dp[i-j]+a[j]); } } } cout<<dp[n]; return 0; }
信息
- ID
- 2824
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 8
- 标签
- 递交数
- 76
- 已通过
- 9
- 上传者