hdu 1421 搬寝室(dp)
作者:互联网
Problem Description
搬寝室是很累的,xhd深有体会.时间追述2006年7月9号,那天xhd迫于无奈要从27号楼搬到3号楼,因为10号要封楼了.看着寝室里的n件物品,xhd开始发呆,因为n是一个小于2000的整数,实在是太多了,于是xhd决定随便搬2*k件过去就行了.但还是会很累,因为2*k也不小是一个不大于n的整数.幸运的是xhd根据多年的搬东西的经验发现每搬一次的疲劳度是和左右手的物品的重量差的平方成正比(这里补充一句,xhd每次搬两件东西,左手一件右手一件).例如xhd左手拿重量为3的物品,右手拿重量为6的物品,则他搬完这次的疲劳度为(6-3)^2 = 9.现在可怜的xhd希望知道搬完这2*k件物品后的最佳状态是怎样的(也就是最低的疲劳度),请告诉他吧.
Input 每组输入数据有两行,第一行有两个数n,k(2<=2*k<=n<2000).第二行有n个整数分别表示n件物品的重量(重量是一个小于2^15的正整数).
Output 对应每组输入数据,输出数据只有一个表示他的最少的疲劳度,每个一行.
Sample Input 2 1 1 3 Sample Output 4 思路:首先,我们应该对输入数据进行一次排序,按顺序排好后很容易可以知道相邻两个的物品重量差一定是对于这两个物品来说是最小的。 DP[ i ][ j ] = min(DP[ i-1 ][ j ],DP[ i - 2][ j - 1] + (a[ i ] - a [ i - 1 ])^2)
#include <cstdio> #include <map> #include <iostream> #include<cstring> #include<bits/stdc++.h> #define ll long long int #define M 6 using namespace std; inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;} int moth[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; int dir[4][2]={1,0 ,0,1 ,-1,0 ,0,-1}; int dirs[8][2]={1,0 ,0,1 ,-1,0 ,0,-1, -1,-1 ,-1,1 ,1,-1 ,1,1}; const int inf=0x3f3f3f3f; const ll mod=1e9+7; int n,k; int a[2007]; int dp[2007][2007]; //表示前i个物品中选择了j对 int main(){ ios::sync_with_stdio(false); while(cin>>n>>k){ for(int i=1;i<=n;i++) cin>>a[i]; sort(a+1,a+1+n); //保证相差最小 for(int i=1;i<=n;i++) for(int j=1;j<=k;j++) dp[i][j]=inf; dp[0][0]=0; for(int i=2;i<=n;i++) for(int j=1;2*j<=i;j++){ dp[i][j]=min(dp[i-1][j],dp[i-2][j-1]+(a[i]-a[i-1])*(a[i]-a[i-1])); } cout<<dp[n][k]<<endl; } return 0; }
标签:1421,hdu,xhd,int,ll,30,include,31,dp 来源: https://www.cnblogs.com/wmj6/p/10392341.html