zoukankan      html  css  js  c++  java
  • hdu 4283 You Are the One(区间dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4283

    题意:有队屌丝,每个人有一个愤怒值D,如果他是第K个上场,不开心指数就为(K-1)*D。但是边上有一个小黑屋(其实就是个堆栈)

    可以先把人放置一下改变一下上场顺序,最后要得到总的不开心值最小。

    数据比较小可以随意的套循环,简单的区间dp模版套3层for

    设dp[i][j]表示从第i个人开始到第j个人愤怒总值是多少,可以想到

    dp[i][j]=min(dp[i][j],dp[i+1][j]+a[i]*(k-i)(k表示i~j之间的数)+dp[k+1][j]+(k-i+1)*(sum[j]-sum[k])(sum表示前缀和))

    这个转移方程很好理解,就是第i位的人要么先上要么放到后面。至于这个sum前缀和

    为什么不会受到交换后影响,由于用到sum前缀和的都是移动后面的所以不会受到影响。

    #include <iostream>
    #include <cstring>
    #include <string>
    #define inf 1<<27;
    using namespace std;
    int a[110] , dp[110][110] , sum[110];
    int main() {
        int t , n , ans = 0;
        cin >> t;
        while(t--) {
            ans++;
            cin >> n;
            memset(sum , 0 , sizeof(sum));
            memset(dp , 0 , sizeof(dp));
            for(int i = 1 ; i <= n ; i++) {
                cin >> a[i];
                sum[i] = sum[i - 1] + a[i];
                dp[i][i] = 0;
            }
            for(int i = 1 ; i <= n ; i++) {
                for(int j = i + 1 ; j <= n ; j++) {
                    dp[i][j] = inf;
                }
            }
            for(int i = 1 ; i <= n - 1 ; i++) {
                for(int j = 1 ; j <= n && i + j <= n ; j++) {
                    for(int k = j ; k <= i + j ; k++) {
                        dp[j][i + j] = min(dp[j][i + j] , dp[j + 1][k] + a[j] * (k - j) + dp[k + 1][j + i] + (k - j + 1) * (sum[i + j] - sum[k]));
                    }
                }
            }
            cout << "Case #" << ans << ": " << dp[1][n] << endl;
        }
        return 0;
    }
    
  • 相关阅读:
    hdu 4768 Flyer 二分
    hdu 4767 Bell
    hdu 4759 Poker Shuffle 二进制
    uva 12589
    zoj 3057 Beans Game 博弈论
    poj 2480 Longge's problem 积性函数
    重新启程
    【Luogu P1502】 窗口的星星
    【BZOJ1855】[Scoi2010] 股票交易
    【BZOJ1122】[POI2008] 账本BBB
  • 原文地址:https://www.cnblogs.com/TnT2333333/p/6497346.html
Copyright © 2011-2022 走看看