[题解]UVA10271 佳佳的筷子 Chopsticks

思路

这是一道 DP 好题,首先要搞清楚 dp 数组的含义,以及状态转移。

我们 dpi,j 的含义是:取前 i 个数,形成 j 个三元组的最小权值和。

然后我们就可以来推状态转移方程了。

首先 dp 数组的初始值要设为无穷大,因为我们要求的是最小值所以我们需要设为无穷大

然后,我们要将 dpi,0 赋为 0,因为我们不选三元组,所以权值和自然就是 0 了。

最后我们的方程是有两种情况的,一种是选,一种是不选。

选的话就是用 dpi2,j1 加上本次新增加的这个三元组的权值 (ai1ai)2,即:dpi2,j1+(ai1ai)

不选就简单了,就是上一个状态嘛,即:dpi1,j

这样我们的状态转移方程就出来了,即:dpi,j=min(dpi1,j,dpi2,j1+(ai1ai)2)

注:我们的 a 数组需要倒序输入,这样才好组成三元组。

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 国际」许可协议进行许可。

posted @   WBIKPS  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
点击右上角即可分享
微信分享提示