• poj1651【区间DP·基础】


    题意:
    给你一串数字,头尾不能动,每次取出一个数字,这个数字贡献=该数字与左右相邻数字的乘积,求一个最小值。
    思路:
    用dp[s][t]去代表s到t的最小值,包括a[s]和a[t],然后从区间为3开始枚举,对每个小区间枚举一个取出的数,状态转移方程就是:dp[s][t]=min(dp[s][k]+dp[k][j]+a[i]*a[k]*a[j];
    PS:
    操蛋的区间DP…想了半个小时毛都没想出来。看了自己的思路,是没有去重视这个取的问题,状态的改变就是取的之后,应该从这里一直去思考,对于子结构的观念也不强,怎么说啊,子结构就是一个前一状态,其实就是对于dp[i][j]数组的定义感不强,所以对于转化也不可能有多大的进展。说了那么多,解题最应该的就是这个对于某个位置的取一直要去思考,然后就会想到枚举每个位置了。卧槽,好弱啊,就是这么弱啊,其实没听到区间DP,也会写啊,也不知道为毛这都想不到,看重DP了吧,,,不知道怎么说了,妈的。
    贴一发大哥给我的**挫**code…

    #include <stdio.h>
    #include <limits.h>
    #include <string.h>
    #define min(a, b) a < b ? a : b
    
    int a[200];
    int dp[200][200];
    
    int main()
    {
        int n;
        scanf("%d", &n);
        for(int i = 1;i <= n;++i)
            scanf("%d", &a[i]);
        memset(dp, 0, sizeof(dp));
        for(int l = 3;l <= n;++l) //区间长度
        {
            for(int s = 1;s <= n - l + 1;++s) //区间开头
            {
                int e = s + l - 1; //长度为l的[s, e]这个区间
                dp[s][e] = INT_MAX;
                for(int k = s + 1;k <= e - 1;++k) //最后一次取哪个
                {
                    dp[s][e] = min(dp[s][e],dp[s][k] + dp[k][e] + a[s] * a[k] * a[e]);
                }
            }
        }
        printf("%d
    ", dp[1][n]);
        return 0;
    }
  • 相关阅读:
    js中面向对象的写法
    js中防止全局变量被污染的方法
    移动端的头部标签和meta
    励志
    UX是什么?
    HTTP
    Django RestFramework (DRF)
    Vue(一)
    Vue-基础
    Vue-es6基础语法
  • 原文地址:https://www.cnblogs.com/keyboarder-zsq/p/5934897.html
Copyright © 2020-2023  润新知