zoukankan      html  css  js  c++  java
  • 【动规】筷子

    原题传送门

    题目描述

    叉烧的生日快到了,他决定邀请K-1个朋友来他家吃饭,加上叉烧一共有K个人。
    叉烧有N根筷子,这些筷子很奇特,长短不一。现在叉烧需要整理出K双筷子,使每双筷子长度差的平方和最小。

    输入格式

    第一行为两个用空格隔开的整数N,K(1≤N≤100, 0≤K≤50),表示有N根筷子,K个人。
    第二行共有N个用空格隔开的整数为Ti,表示每根筷子的长度。1≤Ti≤50

    输出格式

    如果凑不齐K双筷子,输出-1,否则输出一个整数,代表使每双筷子长度差的平方和。

    样例输入

    4 1
    1 3 6 10

    样例输出

    4


    说点啥

    这道题难度有点大,至少对我如此,难点在于找到动态规划的i和j分别代表什么才能表示出每个状态,找到这个之后就比较简单了,比赛当时我没找到,赛后才灵光一现反应过来。

    先排序,然后i表示已凑集几双筷子,j表示处理到第几双筷子,剩下就很简单,大家都明白了

    Code

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    
    int n,k,t[105],c[105],dp[55][105],Max=99999999;
    int main()
    {
    	cin>>n>>k;
    	for(int i=1;i<=n;i++)
    	cin>>t[i];
    	
    	sort(t+1,t+n+1);
    	for(int i=2;i<=n;i++)
    		c[i]=(t[i]-t[i-1])*(t[i]-t[i-1]);
    	for(int i=1;i<=k;i++)
    		for(int j=1;j<=i*2-1;j++)
    			dp[i][j]=Max;
    	
    	for(int i=1;i<=k;i++)
    		for(int j=1;j<=n;j++)
    			if(dp[i][j]!=Max)
    				dp[i][j]=min(dp[i][j-1],dp[i-1][j-2]+c[j]);
    				
    	if(dp[k][n]==Max)
    		cout<<"-1"<<endl;
    	else
    		cout<<dp[k][n]<<endl;
    	return 0;
    }
    
  • 相关阅读:
    CentOS7下安装Scrapy
    阿里云ECS提示RHSA-2017:3263: curl security update
    CentOS 7.0安装配置LAMP服务器(Apache+PHP+MariaDB)
    Electron: 从零开始写一个记事本app
    flask请求流程
    编写Dockerfile
    docker-compose使用
    redis持久化切换rdb到aof
    RESTful API规范
    介绍importlib
  • 原文地址:https://www.cnblogs.com/gongdakai/p/13579577.html
Copyright © 2011-2022 走看看