[题解]UVA10271 佳佳的筷子 Chopsticks
思路
这是一道 DP 好题,首先要搞清楚 数组的含义,以及状态转移。
我们 的含义是:取前 个数,形成 个三元组的最小权值和。
然后我们就可以来推状态转移方程了。
首先 数组的初始值要设为无穷大,因为我们要求的是最小值所以我们需要设为无穷大
然后,我们要将 赋为 ,因为我们不选三元组,所以权值和自然就是 了。
最后我们的方程是有两种情况的,一种是选,一种是不选。
选的话就是用 加上本次新增加的这个三元组的权值 ,即:。
不选就简单了,就是上一个状态嘛,即:。
这样我们的状态转移方程就出来了,即:
注:我们的 数组需要倒序输入,这样才好组成三元组。
Code
#include <bits/stdc++.h>
using namespace std;
const int N = 5010;
int T,k,n;
int arr[N];
int dp[N][N];
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> T;
while (T--){
cin >> k >> n;
k += 8;//要组成 k + 8 个三元组,所以需要加上 8
for (int i = n;i;i--) cin >> arr[i];//倒序输入
memset(dp,127,sizeof(dp));//赋为 INF
for (int i = 1;i <= n;i++) dp[i][0] = 0;
for (int i = 3;i <= n;i++){//枚举 i,j
for (int j = 1;j <= k;j++){
if (i >= 3 * j) dp[i][j] = min(dp[i - 2][j - 1] + (arr[i - 1] - arr[i]) * (arr[i - 1] - arr[i]),dp[i - 1][j]);
//这里 i >= 3 * j 的原因是:要组成 j 个三元组至少也得要 3 * j 个数
}
}
cout << dp[n][k] << endl;
}
return 0;
}
作者:WaterSun
出处:https://www.cnblogs.com/WaterSun/p/18268814
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】