Everything is great about Ilya's city, except the roads. The thing is, the only ZooVille road is represented as n holes in a row. We will consider the holes numbered from 1 to n, from left to right.
Ilya is really keep on helping his city. So, he wants to fix at least k holes (perharps he can fix more) on a single ZooVille road.
The city has m building companies, the i-th company needs ci money units to fix a road segment containing holes with numbers of at least li and at most ri. The companies in ZooVille are very greedy, so, if they fix a segment containing some already fixed holes, they do not decrease the price for fixing the segment.
Determine the minimum money Ilya will need to fix at least k holes.
The first line contains three integers n, m, k (1 ≤ n ≤ 300, 1 ≤ m ≤ 105, 1 ≤ k ≤ n). The next m lines contain the companies' description. The i-th line contains three integers li, ri, ci (1 ≤ li ≤ ri ≤ n, 1 ≤ ci ≤ 109).
Print a single integer — the minimum money Ilya needs to fix at least k holes.
If it is impossible to fix at least k holes, print -1.
Please, do not use the %lld specifier to read or write 64-bit integers in С++. It is preferred to use the cin, cout streams or the %I64d specifier.
10 4 6 7 9 11 6 9 13 7 7 7 3 5 6
17
10 7 1 3 4 15 8 9 8 5 6 8 9 10 6 1 4 2 1 4 10 8 10 13
2
10 1 9 5 10 14
-1
题目大意:
给你N个洞,需要进行填补至少K个,现在有M个施工队,对于这M个施工队的元素有三个:
L,R,C.表示这个施工队只能对于区间【L,R】的洞进行填补,雇佣这个施工队就需要花费C单位的价钱。
问至少填补K个洞的最小花费。
思路:
显然直接贪心是不可取的,我们考虑Dp.对于Dp来讲,对于最终结果的无非有三种状态:
①位子
②填补了多少个洞
③花费为多少。
那么我们设定Dp【i】【j】表示为从左到右的Dp,到位子i,一共填补了j个洞口的最小花费。
那么状态转移过程我们可以O(n*k*m)去求,然而时间复杂度不允许;
所以我们要优化这个m.观察到数据范围N不大,所以我们考虑预处理出cost【i】【j】表示填补区间【i,j】的洞口的最小花费.
因为是线性的动态规划,所以预处理cost【i】【j】的时候没有必要O(m*n^2)去做,直接O(m*n*2)的以左右端点各作为起点和终点去画一段即可:
那么状态转移方程就可以O(n^3)的去转移:
注意实现代码的细节就没有别的难点了。
Ac代码:
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define ll __int64
struct node
{
int x,y;
ll w;
}a[100040];
ll cost[305][305];
ll dp[305][305];
const ll INF=100000000000000000;
int main()
{
int n,m,kk;
while(~scanf("%d%d%d",&n,&m,&kk))
{
for(int i=0;i<=n;i++)
{
for(int j=0;j<=n;j++)
{
cost[i][j]=INF;
dp[i][j]=INF;
}
}
for(int i=1;i<=m;i++)
{
int x,y,w;
scanf("%d%d%I64d",&a[i].x,&a[i].y,&a[i].w);
for(int j=a[i].x;j<=a[i].y;j++)
{
cost[j][a[i].y]=min(cost[j][a[i].y],a[i].w);
cost[a[i].x][j]=min(cost[a[i].x][j],a[i].w);
}
cost[a[i].x][a[i].y]=min(cost[a[i].x][a[i].y],a[i].w);
}
dp[0][0]=0;
for(int i=1;i<=n;i++)
{
for(int j=0;j<=i;j++)
{
dp[i][j]=min(dp[i][j],dp[i-1][j]);
for(int k=1;k<=i;k++)
{
if(j-(i-k+1)>=0)
{
dp[i][j]=min(dp[i][j],cost[k][i]+dp[k-1][j-(i-k+1)]);
}
}
}
}
if(dp[n][kk]==INF)printf("-1\n");
else
printf("%I64d\n",dp[n][kk]);
}
}