6 4
1 -3 5 1 -2 3
7
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int n,m,f[300010],p[300010],sum=0,tail,head,x,ans=0; 5 int main() 6 { 7 scanf("%d%d",&n,&m); 8 head=1,tail=2; 9 for(int i=1;i<=n;i++){ 10 scanf("%d",&x);sum+=x; 11 while(f[tail-1]>=sum && tail>head) tail--; 12 f[tail]=sum;p[tail]=i; 13 tail++; 14 while(i-p[head]>m) head++; 15 if(sum-f[head]>ans) ans=sum-f[head]; 16 } 17 printf("%d\n",ans); 18 return 0; 19 }
烽火传递:
给定n个非负整数,选择其中若干数字,使得每连续k个数中至少有一个数被选出。 要求选择的数字之和尽可能小。
据说是NOIP考试题,但是我没有在OnlineJudge上找到,所以也没有测评
1 #include<iostream> 2 #include<cstdio> 3 #define maxn 1000010 4 using namespace std; 5 int l=0,r=0,n,m,a[maxn],q[maxn*2],f[maxn]; 6 int main() 7 { 8 scanf("%d%d",&n,&m); 9 for(int i=1;i<=n;i++) scanf("%d",&a[i]); 10 for(int i=1;i<=n;i++){ 11 while(l<r&&i-q[l]>m) l++; 12 f[i]=f[q[l]]+a[i]; 13 while(l<r&&f[q[r]]>f[i]) r--; 14 q[++r]=i; 15 } 16 int ans=0x7f; 17 for(int i=n-m+1;i<=n;i++) ans=min(ans,f[i]); 18 printf("%d\n",ans); 19 return 0; 20 }
相同的地方是两个题都是单调队列优化+DP
原文:http://www.cnblogs.com/suishiguang/p/6361632.html