标签:
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3427
可以证明最终序列为-1...0....1
因为首先如果 a(i-1) 为-1或0,执行操作不会让答案变优。
然后,如果可以加到大于1的某个数字,一定可以加到1,显然加到1更佳。
然后简单dp,f[i][j]表示第i位为j的最少步数。
#include <cstdio> #include <cstring> #include <algorithm> #define N 1000010 using namespace std; int f[N][3],n,a[N]; int min(int a,int b,int c,int d){ return min(min(a,d),min(b,c)); } int min(int a,int b,int c){ return min(a,min(b,c)); } int calc(int x,int to,int v){ v--; if(x==to) return 0; if(x+v==to) return 1; if(x+2*v==to) return 2; return 0x3f3f3f3f; } int main(){ memset(f,0x3f,sizeof(f)); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]),a[i]++; f[1][a[1]]=0; for(int i=2,s1,s2;i<=n;i++){ f[i][0]=min(f[i][0],f[i-1][0]+calc(a[i],0,0)); f[i][1]=min(f[i][1],f[i-1][1]+calc(a[i],1,1),f[i-1][0]+calc(a[i],1,0)); f[i][2]=min(f[i][2],f[i-1][2]+calc(a[i],2,2),f[i-1][1]+calc(a[i],2,1),f[i-1][0]+calc(a[i],2,0)); } int ans=min(f[n][0],f[n][1],f[n][2]); if(ans>=0x3f3f3f3f) puts("BRAK"); else printf("%d\n",ans); return 0; }
标签:
原文地址:http://www.cnblogs.com/lawyer/p/4550798.html