题目描述
After the last debacle involving Farmer John's circular barn, one would think he had learned his lesson about non-traditional architecture. However, he thinks he can still make his circular barn (from the preceding problem) function properly by allowing multiple cows into each room. To recap, the barn consists of a ring of nn rooms, numbered clockwise from 1 \ldots n1…n around the perimeter of the barn ( 3 \leq n \leq 1003≤n≤100 ). Each room has doors to its two neighboring rooms, and also a door opening to the exterior of the barn.
Farmer John wants exactly r_iri cows to end up in room ii ( 1 \leq r_i \leq 1,000,0001≤ri≤1,000,000 ). To herd the cows into the barn in an orderly fashion, he plans to unlock kk exterior doors ( 1 \leq k \leq 71≤k≤7 ), allowing the cows to enter through only those doors. Each cow then walks clockwise through the rooms until she reaches a suitable destination. Farmer John wants to unlock the exterior doors that will cause his cows to collectively walk a minimum total amount of distance after entering the barn (they can initially line up however they like outside the kk unlocked doors; this does not contribute to the total distance in question). Please determine the minimum total distance his cows will need to walk, if he chooses the best kk such doors to unlock.
还是这个谷仓,有n(3<=n<=100)个房间。当然,奶牛可能不止n头了。奶牛都在谷仓外面。现在约翰想要让第i个房间关ri(1<=ri<=1000000)头奶牛按顺时针方向走,直到到达合适的房间。这k(1<=k<=7)个门开在哪里,才能使得奶牛们走的路程最少。奶牛在谷仓外可以随意移动,可以随意选择k个门中的任意一个排队,这不计入最终的路程。
输入输出格式
输入格式:
The first line of input contains nn and kk . Each of the remaining nn lines
contain r_1 \ldots r_nr1…rn .
输出格式:
Please write out the minimum amount of distance the cows need to travel.
输入输出样例
输入样例#1: 复制
6 2 2 5 4 2 6 2
输出样例#1: 复制
14
说明
Farmer John can unlock doors 2 and 5. 11 cows enter at door 2 and walk a total
distance of 8 to get to rooms 2, 3, and 4. 10 cows enter at door 5 and walk a
total distance of 6 to get to rooms 5, 6 and 1.
思路:破环为链,dp[i][j][k]表示i房必须开门,i到j房共开k扇门,牛充满i到j房走过的距离。预处理O(k*n*n*n)暴力dp就行。
# include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL num[203][203], a[203], dp[203][203][8];
int main()
{
int n, K;
scanf("%d%d",&n,&K);
memset(dp, 0x3f, sizeof(dp));
K = min(n, K);
for(int i=1; i<=n; ++i) scanf("%lld",a+i), a[i+n] = a[i];
for(int i=1; i<=2*n; ++i)
{
for(int j=i; j<=2*n&&j-i+1<=n; ++j)
{
num[i][j] = num[i][j-1] + a[(j<=n)?j:j-n]*(j-i);
dp[i][j][1] = num[i][j];
}
}
for(int k=2; k<=K; ++k)
for(int i=1; i<=n&&i+k-1<=2*n; ++i)
for(int j=i+k-1; j-i+1<=n; ++j)
for(int t=i+k-1; t<=j; ++t)
dp[i][j][k] = min(dp[i][j][k], dp[i][t-1][k-1]+num[t][j]);
LL ans = 0x3f3f3f3f3f3f3f3f;
for(int i=1; i+n-1<=2*n; ++i)
ans = min(ans, dp[i][i+n-1][K]);
printf("%lld\n",ans);
return 0;
}