[关闭]
@ysner 2018-08-03T18:11:50.000000Z 字数 1945 阅读 1859

[POI2013]BAJ-Bytecomputer

DP


题面

给一个只包含的数列,每次操作可以让,求最少操作次数使得序列单调不降。

解析

显然只能设状态表示已处理完第个数,第个数转化为的最小操作次数。
本题难度在于考虑转移条件。
话说我一开始是这么写的:(充分体现了我蒟蒻的本质)

  1. fp(i,0,n) dp[i][0]=dp[i][1]=dp[i][2]=inf;
  2. dp[1][a[1]+1]=1;
  3. fp(i,2,n)
  4. {
  5. if(a[i]==-1)
  6. {
  7. dp[i][0]=dp[i-1][0];
  8. //dp[i][1]=dp[i-1][2];
  9. dp[i][2]=dp[i-1][2]+2;
  10. }
  11. if(a[i]==0)
  12. {
  13. dp[i][0]=dp[i-1][0]+1;
  14. dp[i][1]=dp[i-1][1];
  15. dp[i][2]=dp[i-1][2]+1;
  16. }
  17. if(a[i]==1)
  18. {
  19. dp[i][0]=dp[i-1][0]+2;
  20. dp[i][1]=dp[i-1][0]+1;
  21. dp[i][2]=dp[i-1][2];
  22. }
  23. }
  24. re ll ans=min(dp[n][0],min(dp[n][1],dp[n][2]));

然后答案大了很多。

那应该怎样转移呢?

至于一些细节如取、对答案的贡献等自己想想吧。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<algorithm>
  7. #include<vector>
  8. #define re register
  9. #define il inline
  10. #define ll long long
  11. #define inf 1e18
  12. #define max(a,b) ((a)>(b)?(a):(b))
  13. #define min(a,b) ((a)<(b)?(a):(b))
  14. #define fp(i,a,b) for(re int i=a;i<=b;i++)
  15. #define fq(i,a,b) for(re int i=a;i>=b;i--)
  16. using namespace std;
  17. const int mod=1e9+7,N=1e6+100;
  18. ll dp[N][3],n,a[N];
  19. il ll gi()
  20. {
  21. re ll x=0,t=1;
  22. re char ch=getchar();
  23. while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
  24. if(ch=='-') t=-1,ch=getchar();
  25. while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
  26. return x*t;
  27. }
  28. int main()
  29. {
  30. n=gi();fp(i,1,n) a[i]=gi();
  31. fp(i,0,n) dp[i][0]=dp[i][1]=dp[i][2]=inf;
  32. dp[1][a[1]+1]=0;
  33. fp(i,2,n)
  34. {
  35. if(a[i]==-1)
  36. {
  37. dp[i][0]=dp[i-1][0];
  38. dp[i][1]=(a[i-1]==1)?min(dp[i-1][0],dp[i-1][1])+1:inf;
  39. dp[i][2]=(a[i-1]==1)?min(dp[i-1][0],min(dp[i-1][1],dp[i-1][2]))+2:dp[i-1][2]+2;
  40. }
  41. if(a[i]==0)
  42. {
  43. dp[i][0]=dp[i-1][0]+1;
  44. dp[i][1]=min(dp[i-1][1],dp[i-1][0]);
  45. dp[i][2]=(a[i-1]==1)?min(dp[i-1][0],min(dp[i-1][1],dp[i-1][2]))+1:dp[i-1][2]+1;
  46. }
  47. if(a[i]==1)
  48. {
  49. dp[i][0]=dp[i-1][0]+2;
  50. dp[i][1]=(a[i-1]==-1)?min(dp[i-1][0],dp[i-1][1])+1:dp[i-1][0]+1;
  51. dp[i][2]=min(dp[i-1][0],min(dp[i-1][1],dp[i-1][2]));
  52. }
  53. }
  54. re ll ans=min(dp[n][0],min(dp[n][1],dp[n][2]));
  55. if(ans>=inf) puts("BRAK");
  56. else printf("%lld\n",ans);
  57. return 0;
  58. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注