# 单调队列优化DP能到什么程度（今天中午进行的实验记录）

f[i] = min( f[j] ) + a[i]

【实验方程】：

f[i] = min ( f[j] ) + a[i] ( 1<= j <= i-1 )

【实验过程】：

1、传统的二重循环判定：

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<ctime>
#include<cstdlib>
#define INF 0x7fffffff
using namespace std;
int main()
{
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
int n,a[100005],f[100005];
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
f[1]=a[1];
for(int i=2;i<=n;i++)
{
int Min=INF;
for(int j=1;j<i;j++)
if(Min>f[j]) Min=f[j];
f[i]=Min+a[i];
}
for(int i=1;i<=n;i++)
{
printf("%d",f[i]);
if(i==n) printf("\n");
else printf(" ");
}
return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<ctime>
#include<cstdlib>
#define INF 0x7fffffff
using namespace std;
int main()
{
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
int n,a[100005],f[100005];
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
f[1]=a[1];
int Min=f[1];
for(int i=2;i<=n;i++)
{
f[i]=Min+a[i];
if(f[i]<Min) Min=f[i];
}
for(int i=1;i<=n;i++)
{
printf("%d",f[i]);
if(i==n) printf("\n");
else printf(" ");
}
return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<ctime>
#include<cstdlib>
#define INF 0x7fffffff
using namespace std;
int main()
{
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
int n,a[100005],f[100005];
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
f[1]=a[1];
for(int i=2;i<=n;i++)
{
f[i]=f[q[1]]+a[i];
//printf("f[q[1]]=%d\n",f[q[1]]);
//printf("f[%d]=%d\n",i,f[i]);
while(f[i]<=f[q[tail]] && 1<=tail) tail--;
q[++tail]=i;
}
for(int i=1;i<=n;i++)
{
printf("%d",f[i]);
if(i==n) printf("\n");
else printf(" ");
}
return 0;
}