• HDU4283 You Are the One(区间dp)


    题意:

    有n个选手,每个人都有一个愤怒值a[i],当第i位选手是第k个出场的时候,他的愤怒值为(k-1)*a[i];

    有一个黑箱子(堆栈),可以往里面放人(改变出场次序),问最小的愤怒值。

    解析:

    dp[i][j]保存的是i到j之间最大的愤怒值减小量。

    假设第i个人第k个上场,那么后面第i+1到第K个人就会都提前一名上场,第K个人到第J个人愤怒值不变。

    也就是dp[i][j]=min(a[i]*(k-1)+sum[i]-sum[k]+dp[i+1][k]+dp[k+1][j]);

    最后输出原始值+减小量即可

    附上ac代码:

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #include <cstdio>
    using namespace std;
    #define N 105
    int a[N],sum[N],dp[N][N];
    int main()
    {
        //freopen("in.txt","r",stdin);
        int t;
        scanf("%d",&t);
        for(int y=1;y<=t;y++)
        {
            int n,ans=0;
            scanf("%d",&n);
            sum[0]=0;
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&a[i]);
                sum[i]=sum[i-1]+a[i];
                ans=ans+a[i]*(i-1);
            }
            memset(dp,0,sizeof(dp));
            for(int i=1;i<n;i++)
                dp[i][i+1]=min(dp[i][i+1],a[i]-a[i+1]);
            for(int l=2;l<n;l++)
            {
                for(int i=1;i+l<=n;i++)
                {
                    int j=i+l;
                    for(int k=i;k<=j;k++)
                        dp[i][j]=min(dp[i][j],a[i]*(k-i)-sum[k]+sum[i]+dp[i+1][k]+dp[k+1][j]);
                }
            }
            printf("Case #%d: %d
    ",y,ans+dp[1][n]);
        }
        return 0;
    }
  • 相关阅读:
    DHCP协议详解(硬件方面原理)
    ASP.NET安全认证
    JAVA打包成.jar可运行项目
    JAVA菜单事件
    JAVA事件概述
    JAVA对话框事件
    各种事件汇聚
    把原来可空的列变成主键
    搜索模式中的所有表
    JAVA选项事件
  • 原文地址:https://www.cnblogs.com/d-e-v-i-l/p/5296782.html
Copyright © 2020-2023  润新知