题意:买瓜,每天的瓜有不同的价格和xu命时间,要求能苟到第n天的最小代价

定义DP方程\(dp[i]\),指苟到第\(i\)天的最小代价,所求即为\(dp[n]\)

那么怎么转移就是问题,这里的状态表示显然不能转移,因为哪一天买的瓜苟到哪一刻都不知道,空间太大不足以维护

再定义一个st表\(st[i]\),表示【能够】苟到第\(i\)天的最小代价,那么转移就是dp[i]=min(dp[i-1]+瓜,st[i...n]),后者表示不买瓜直接xu命

st表肯定是一个每一位都单调非增序列,应该可以用单调队列优化(然而不会),所以还是放到线段树上更新了..

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<string>
#include<vector>
#include<stack>
#include<queue>
#include<bitset>
#include<set>
#include<map>
#define rep(i,j,k) for(register int i=j;i<=k;i++)
#define rrep(i,j,k) for(register int i=j;i>=k;i--)
#define erep(i,u) for(register int i=head[u];~i;i=nxt[i])
#define iin(a) scanf("%d",&a)
#define lin(a) scanf("%lld",&a)
#define din(a) scanf("%lf",&a)
#define s0(a) scanf("%s",a)
#define s1(a) scanf("%s",a+1)
#define print(a) printf("%lld",(ll)a)
#define enter putchar('\n')
#define blank putchar(' ')
#define println(a) printf("%lld\n",(ll)a)
#define IOS ios::sync_with_stdio(0)
using namespace std;
const int maxn = 1e5+11;
const int MOD = 2520;
const double eps = 1e-10;
typedef long long ll;
const ll oo = 1ll<<60;
ll read(){
ll x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
ll dp[maxn],a[maxn],b[maxn],n;
struct ST{
ll mn[maxn<<2];
#define lc o<<1
#define rc o<<1|1
void build(int o,int l,int r){
mn[o]=oo;
if(l==r)return;
int m=l+r>>1;
build(lc,l,m);
build(rc,m+1,r);
}
void pu(int o){
mn[o]=min(mn[lc],mn[rc]);
}
void update(int o,int l,int r,int k,ll v){
if(l==r){
mn[o]=min(v,mn[o]);
return;
}
int m=l+r>>1;
if(k<=m) update(lc,l,m,k,v);
else update(rc,m+1,r,k,v);
pu(o);
}
ll query(int o,int l,int r,int L,int R){
if(L<=l&&r<=R) return mn[o];
int m=l+r>>1;
ll ans=oo;
if(L<=m) ans=min(ans,query(lc,l,m,L,R));
if(R>m) ans=min(ans,query(rc,m+1,r,L,R));
return ans;
}
}st;
int main(){
while(cin>>n){
rep(i,1,n) a[i]=read();
rep(i,1,n) b[i]=min(read(),n);
st.build(1,1,n);
dp[0]=0;
dp[1]=a[1];st.update(1,1,n,b[1],dp[1]);
rep(i,2,n){
dp[i]=dp[i-1]+a[i];
st.update(1,1,n,min(i+b[i]-1,n),dp[i]);//mai gua
ll t=st.query(1,1,n,i,n);//xu ming
if(t<dp[i]) dp[i]=t;
}
println(min(dp[n],st.query(1,1,n,n,n)));
}
return 0;
}

最新文章

  1. bzoj4691: Let There Be Light
  2. jvm性能参数与调优
  3. 开源项目asmjit&mdash;&mdash;调用自定义方法demo以及windbg调试
  4. Set Php show errors
  5. error: jump to label ‘XXXX’ [-fpermissive]
  6. link标签和script标签跑到body下面,网页顶部有空白
  7. mysql 权限控制
  8. Mysql导出导入乱码问题解决
  9. spring中基础核心接口总结
  10. Linux 各类软件整理汇总
  11. 一把刀终极配置 For XP v2.0 免费绿色版
  12. Servlet和web服务器关系
  13. CF765F Souvenirs
  14. Ubuntu下安装chrome浏览器
  15. 谈lisp
  16. 开发环境 pyenv
  17. Android为TV端助力 很详细的序列化过程Parcelable
  18. php如何实现图片点击下载,并保存本地?-----本例子为二维码的生成图片,并支持点击下载
  19. 数据库之MySQL ERROR 1698 (28000) 错误:Access denied for user &#39;root&#39;@&#39;localhost&#39;&quot; error【摘抄】
  20. 立即响应ScrollView上的子视图的手势

热门文章

  1. 414. Third Maximum Number数组中第三大的数字
  2. js颜色拾取器
  3. c语言实践:求两个数的最大公约数
  4. Entity Framework edmx(mapping文件)
  5. 通过批处理操作注册表实现winform应用中Webbrowser以指定的IE版本加载网页
  6. Head First Python之2函数模块
  7. c# 求数组的最大值
  8. [database] postgresql 外网访问
  9. C#判断程序调用外部的exe已结束
  10. C# LINQ(3)