• P3558 [POI2013]BAJ-Bytecomputer——线性动归


    题意翻译

    给一个只包含-1,0,1的数列,每次操作可以让a[i]+=a[i-1],求最少操作次数使得序列单调不降

    数据范围为N<=(10^6)

    思路

    线性dp,(f[i][j])表示进行到第(i)个位置,且让第(i)个位置的值为(j)的最少操作次数

    • 如果(a[i]==-1)

    (f[i][-1]=f[i-1][-1])

    (f[i][0]=f[i-1][1]+1)不难发现,这种情况是不符合单调递增的条件的,所以不予考虑

    (f[i][1]=f[i-1][1]+2)

    • 如果(a[i]==0)

    (f[i][-1]=f[i-1][-1]+1)

    (f[i][0]=min(f[i-1][0],f[i-1][-1]))

    (f[i][1]=f[i-1][1]+1)

    • 如果(a[i]==1)

    (f[i][-1]=f[i-1][-1]+2)

    (f[i][0]=f[i-1][-1]+1)

    (f[i][1]=min(f[i-1][0],f[i-1][1],f[i-1][-1]))

    但是下标有负数,怎么办,我们可以加一个偏移量2

    就可以解决了

    目标状态(min..f[n][0],f[n][1],f[n][-1])

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int base=2;
    const int N=1e6+100;
    int f[N][4];
    int a[N];
    int n;
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    	memset(f,0x3f,sizeof(f));
    	f[1][a[1]+base]=0;
    	for(int i=2;i<=n;i++)
    	{
    		if(a[i]==-1)
    		{
    			f[i][-1+base]=f[i-1][-1+base];
    			// f[i][0+base]=f[i-1][1+base]+1;
    			f[i][1+base]=f[i-1][1+base]+2;
    		}
    		else if(a[i]==0)
    		{
    			f[i][-1+base]=f[i-1][-1+base]+1;
    			f[i][0+base]=min(f[i-1][0+base],f[i-1][-1+base]);
    			f[i][1+base]=f[i-1][1+base]+1;
    		}
    		else if(a[i]==1)
    		{
    			f[i][-1+base]=f[i-1][-1+base]+2;
    			f[i][0+base]=f[i-1][-1+base]+1;
    			f[i][1+base]=min(min(f[i-1][0+base],f[i-1][1+base]),f[i-1][-1+base]);
    		}
    	}
    	int ans=min(min(f[n][0+base],f[n][1+base]),f[n][-1+base]);
    	if(ans==0x3f3f3f3f) cout<<"BRAK"<<endl;
    	else cout<<ans<<endl;
    	return 0;
    }
    
  • 相关阅读:
    实验四
    实验一、二
    实验
    网上摘录
    网上摘录(琐碎信息)
    angularJsUIbootstrap系列教程1(使用前的准备)
    angularJS在本机运行时的注意事项
    angularJS在创建指令需要注意的问题(指令中使用ngRepeat)
    angularJsUIbootstrap系列教程2(According)
    ASP.NET Web Forms 4.5的新特性
  • 原文地址:https://www.cnblogs.com/bangdexuanyuan/p/14063714.html
Copyright © 2020-2023  润新知