E Post Lamps
思路:
条件:照亮[0,n]段,选一种灯泡订购,灯泡有价格和向后照射长度,设置了不能放置的位置
1、计算可以选择的最短长度,因为有blocked,因此必须从其前一格放置灯,并且覆盖blocked区域。
计算blocked 的方法:
(1) [0,1,2,3,4,5,6] 3,4,5 不能用,必须选择长度大于等于[2,6] = 4
(2)[0,1,2,3,4,5,6] 0 不能用[0,1] 肯定照射不到 输出-1
(3)[0,1,2,3,4] 覆盖长度max([1,3],[3,4])
取最小花费:
遍历K,从max_blocked 开始计算花费:
如 [0,.....,n] ,给定K,从位置i,走K步i+K,i=i+K ,一直到 i>=n
期间如果i = is blocked,需要blocked 得到blocked前面第一个非blocked。(这里在输入的时候记录一下就好了)
代码:
C++ 11
#include<bits/stdc++.h>
using namespace std;
int s[1000000+10],sl[1000000+10];
bool vis[2000000+10];
int a[1000000+10];
struct price
{int a;//单价int l;//可照明长度
}P[1000000+10];
int main() {int n,m,k;scanf("%d%d%d",&n,&m,&k);int max_block=0,l=1;memset(vis,0,sizeof(vis));memset(s,-1,sizeof(s));for(int i=0;i<m;i++){scanf("%d",&s[i]);vis[s[i]] = 1;if(i==0) {sl[s[i]] = s[i] -1; continue;}if(s[i]==s[i-1]+1) {l += 1; sl[s[i]] = sl[s[i-1]];}else{max_block = max(l+1,max_block);sl[s[i]] = s[i]-1;l = 1;}} int x = 0;if(l>1&&s[m-1]==n) max_block = max(l,max_block);else if(l>1) max_block = max(l+1,max_block);else if(m==1&&s[m-1]==n) max_block =max(l,max_block);else if(m==1) max_block =max(l+1,max_block);for(int i=0;i<k;i++) {scanf("%d",&a[i]);if(i+1>=max_block) {P[x].a = a[i],P[x].l = i+1,x++;//只能选这些}}if(max_block>k||s[0]==0) printf("-1\n");else{long long ans = 1e13;for(int i=0;i<x;i++){long long tmp = 0;int r =0; while(r<n){tmp += P[i].a;r = r+P[i].l;if(vis[r]==1) r = sl[r];} ans = min(ans,tmp);}printf("%lld\n",ans);}return 0;}