标签:标志 终点 短时间 int ++ Optimization dp Road las
题意:
一段长为 \(l\) 的线段上,给定 \(n\) 个限速标志。第 \(i\) 个标志的值为 \(a_i\),位置为 \(s_i\),表示由此标志走到下一标志需要时间 \(a_i(s_{i+1}-s_i)\)。第一个标志在起点 \(0\) 处,且必须选择。
现去掉不超过 \(k\) 个标志,求走完全程的最短时间。
输入均为整数,\(n\le 500\)
思路:
\(f[i][j]\) 表示走到第 \(i\) 个标志,已经选了 \(j\) 个标志且选择第 \(i\) 个标志的最短时间。
枚举 \(i\) 的前面最后一个被选的标志 \(las\),则 \(f[i][j]=min\{f[las][j-1]+a_{las}(s_i-s_{las})\}\),即从 \(las\) 到 \(i\) 这段路都用 \(a_{las}\) 来走。
把终点加上:s[++n]=l
,最后答案为必选终点且已选 \([n-k, n]\) 个点的最短时间。
const int N = 510;
int n, l, k, s[N], a[N], f[N][N];
signed main()
{
cin >> n >> l >> k;
for(int i = 1; i <= n; i++) cin >> s[i];
for(int i = 1; i <= n; i++) cin >> a[i];
s[++n] = l;
memset(f, INF, sizeof f);
f[1][1] = 0;
for(int i = 2; i <= n; i++)
for(int j = 1; j <= i; j++) //至少已选1个
for(int las = 1; las < i; las++)
f[i][j] = min(f[i][j], f[las][j-1] + a[las] * (s[i]-s[las]));
int ans = INF;
for(int i = n - k; i <= n; i++) ans = min(ans, f[n][i]);
cout << ans << endl;
return 0;
}
标签:标志,终点,短时间,int,++,Optimization,dp,Road,las 来源: https://www.cnblogs.com/wushansinger/p/15837993.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。