zoukankan      html  css  js  c++  java
  • You Are the One HDU

    开始读题读了半天,还是参考了大佬的博客
    https://blog.csdn.net/codeswarrior/article/details/81479291
    有一群屌丝,每个屌丝有个屌丝值,如果他第K个上场,屌丝值就为a[i]*(k-1),因为前面有k-1个人在他前面上台,可以把几个人拉进小黑屋来调整,可以把小黑屋当成栈因为先进去的人最后才能出来,使得最后总屌丝值最小

    //定义dp[i][j]表示原序列区间[i,j]的人的最小屌丝值
    //枚举一个中间变量k,设i在区间[i,j]中是第k个上场的
    //这样区间分成了两部分
    //dp[i+1][i+k-1](k-1个人在i之前),dp[i+k][j](之后的人)
    //也就是让[i,i+k-1]这些人进入小黑屋
    //i先进的,那么他前面将有k-1个人
    //他是第k个上场的,之后再让后面的[i+k,j]这些人上场
    //这样很明显i等待了k-1个人屌丝值增长为(k-1)×a[i],而[i+k,j]这些人则等待了k个人,屌丝值增长为k×(这些人的屌丝值之和)
    //因此状态转移公式为
    //dp[i][j]=min(dp[i][j],dp[i+1][i+k-1]+dp[i+k][j]+k×(sum[j]-sum[i+k-1])+a[i]×(k-1))
    //sum[]记录了每个人屌丝值的前缀和
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    int n,a[105],sum[105],dp[105][105];
    int main() {
    	int t,cas = 0;
    	scanf("%d",&t);
    	while(t--) {
    		scanf("%d",&n);
    		memset(sum,0,sizeof(sum));
    		for(int i = 1; i <= n; i++) {
    			scanf("%d",&a[i]);
    			sum[i] = sum[i-1] + a[i];
    		}
    		memset(dp,0,sizeof(dp));
    		for(int i = 1; i <= n; i++) {
    			for(int j = i + 1; j <= n; j++) {
    				dp[i][j] = INF;
    			}
    		}
    		//区间长度 
    		for(int l = 1; l < n; l++)
    			//左端点,		右端点 
    			for(int i = 1; i + l <= n; i++) {
    				//右端点 
    				int j = i + l;
    				//枚举中间量,第几个上场 
    				for(int k = 1; k <= j - i + 1; k++) 
    					dp[i][j] = min(dp[i][j],dp[i+1][i+k-1]+dp[i+k][j]+k*(sum[j]-sum[i+k-1])+a[i]*(k-1));
    			}
    		
    		printf("Case #%d: %d
    ",++cas,dp[1][n]);
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    Python 面向对象
    Python OS 文件
    Python File(文件) 方法
    Python 输入和输出
    Python 的__name__属性
    Python 数据结构
    Docker用途 & 和tomcat的区别
    sql 聚合函数和group by 联合使用
    SQL UNIQUE 约束
    MySQL中如何实现select top n ----Limit
  • 原文地址:https://www.cnblogs.com/QingyuYYYYY/p/12470257.html
Copyright © 2011-2022 走看看