【DP】【排序】书本整理

【DP】【排序】书本整理_第1张图片


思路:

暴力枚举也有30分啊
正解是dp,考场上推出来了
设f[i][j]前i本书有j种摆放方法
则状态转移方程为

f [ i ] [ j ] = m i n ( f [ i ] [ j ] , f [ k k ] [ j − 1 ] + a b s ( e [ i ] . w i d e − e [ k k ] . w i d e ) ) ; f[i][j] = min (f[i][j], f[kk][j - 1] + abs(e[i].wide - e[kk].wide)); f[i][j]=min(f[i][j],f[kk][j1]+abs(e[i].widee[kk].wide));

wide是重量


C o d e Code Code:

#include 
#include 
#include  
using namespace std;

int n,k;
int f[105][105];
struct book
{
	int high,wide;
}e[101001];
bool cmp (book x, book y){return x.high < y.high;}
int main ()
{
	freopen ("book.in","r",stdin);
	freopen ("book.out","w",stdout); 
	scanf ("%d%d", &n,&k);
	for (int i = 1; i <= n; ++i)
	    scanf ("%d%d",&e[i].high, &e[i].wide);
	    k = n - k;//总共 - 去掉的 = 剩下的 
	    sort (e + 1, e + n + 1, cmp);
	for (int i = 1; i <= n; ++i)
	    for (int j = 2 ; j <= min (i, k); ++j)//一的不整齐度为0 
	    {
	    	f[i][j] = 21212121;
	        for(int kk = j - 1; kk < i; kk++)//枚举上本书的摆放位置 
	        f[i][j] = min (f[i][j], f[kk][j - 1] + abs(e[i].wide - e[kk].wide));//dp 
	    }
    int ans = 21212121;
	for (int i = k;i <= n; ++i)
	ans = min (ans,f[i][k]);
	printf("%d",ans);
	return 0;
}

你可能感兴趣的:(DP,排序)