【NOIP模拟】序列
2016-09-19 20:38
309 查看
Description
Solution
这道题有两个方法。方法1:差分加贪心
首先可以求出每个点从a[i]到b[i]的步数c[i]。然后处理出两两之间的差分d[i]。显然在不调整之前(加4),答案的值是∑max(0,d[i]),画一下图就知道了。
那么假设现在对区间[l,r]的每个数加4,那么对于差分的影响,只会影响到l和l-1的差分还有r和r+1之间的差分。
如果现在这里差分有一个3(或2),那么需要在前面找一个-3或-2,因为这样加4之后可以让max(差分,0)更小,而且因为中间的高度已经被两边抵消了,所以加4不会产生新的贡献。
然后O(n)就过去了
Code
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define fo(i,a,b) for(i=a;i<=b;i++) using namespace std; const int maxn=100007; int i,j,k,l,t,n,m,ans,cas,r,da,da1,ans1,ans2[maxn]; int a[maxn],b[maxn],c[maxn],d[maxn],yi,er; int f[maxn][11],g[maxn][11]; int main(){ for(scanf("%d",&cas);cas;cas--){ scanf("%d",&n); fo(i,1,n)scanf("%d",&a[i]); fo(i,1,n)scanf("%d",&k),c[i]=(k-a[i]+4)%4; fo(i,1,n)d[i]=c[i]-c[i-1]; yi=er=ans=0; fo(i,1,n)ans+=max(0,d[i]); fo(i,1,n){ switch(d[i]){ case -3:yi++;break; case -2:er++;break; case 1:break; case 0:break; case -1:break; case 3:{ if(yi)yi--,ans-=2; else if(er)ans--,er--; break; } case 2:{ if(yi)ans--,yi--,er++; break; } } } printf("%d\n",ans); } }
方法2:带证明的优美的DP
设f[i][j]表示i这个位加j次4的最小值。转移很显然,是一个水DP。
但是j的值域怎么办?
事实上,j开到5就好了,可以用上面的差分证明,因为有5中情况,叠在一起,同一个位置最多加5次4。
Code
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define fo(i,a,b) for(i=a;i<=b;i++) using namespace std; const int maxn=100007; int i,j,k,l,t,n,m,ans,cas,r,da,da1; int a[maxn],b[maxn],c[maxn]; int f[maxn][6]; bool bz,az; int chu(int x,int y){ if(x<=y)return y-x; else return (4-x)+y; } int main(){ // freopen("fan.in","r",stdin); for(scanf("%d",&cas);cas;cas--){ scanf("%d",&n); fo(i,1,n)scanf("%d",&a[i]); da=0; fo(i,1,n)scanf("%d",&b[i]),c[i]=chu(a[i],b[i]); memset(f,127,sizeof(f)); f[0][0]=0; fo(i,1,n){ fo(j,0,5){ fo(k,0,5){ if(c[i]+j*4<=c[i-1]+k*4)f[i][j]=min(f[i][j],f[i-1][k]); else f[i][j]=min(f[i][j],f[i-1][k]+abs((c[i]+j*4)-(c[i-1]+k*4))); } } } ans=0x7fffffff; fo(i,0,5)ans=min(f [i],ans); printf("%d\n",ans); } }
相关文章推荐
- [jzoj3889]【NOIP2014模拟10.25B组】序列问题
- [NOIP2017模拟]最佳序列
- 【NOIP 模拟赛】平均数 涂色游戏 序列题解
- 【JZOJ5231】【NOIP2017模拟A组模拟8.5】序列问题
- jzoj5249 【NOIP2017提高A组模拟8.10】文本编辑器 (序列修改类问题,数据结构)
- [NOIP模拟][状压dp][dfs序列][线段树]
- 【NOIP模拟考三】水资源 day2 first 序列计数
- [NOIP模拟] 序列操作
- 【NOIP模拟】 (11.6) T2 序列操作
- 【JZOJ4788】【NOIP2016提高A组模拟9.17】序列
- JZOJ 3518. 【NOIP2013模拟11.6A组】进化序列(evolve)
- {题解}[jzoj2573]【NOIP2011模拟9.20】序列
- NOIP模拟 序列操作【线段树】
- 【NOIP2011模拟9.20】序列
- [NOIP2017模拟]序列操作
- 【jzoj5231】【NOIP2017模拟A组模拟8.5】【序列问题】 【分治】
- jzoj. 3518. 【NOIP2013模拟11.6A组】进化序列(evolve)
- NOIP模拟降雷皇&51nod 1376 最长递增子序列的数量