• hdu 6076 Security Check


      OvO http://acm.hdu.edu.cn/showproblem.php?pid=6076

      2017 Multi-University Training Contest - Team 4 - 1010

      O(n2)的DP的话,

      第二种情况,dp[i][j]=max(max(dp[i][j-1],dp[i-1][j])+1,dp[i-1][j-1]+1),这种情况下dp[i][j]是必然取dp[i-1][j-1]+1的,

      这样对于dp[n][n]就可以类似贪心地处理,每次搜索碰到第二种情况优先取第二种情况,否则就取第一种的最大值。

      而在第一种状况下,因为k很小,所以要搜索的状态其实是很少的。

      对于第二种状况,拿一个向量记录每条对角线上不符合状况二的情况,这样每次搜到第二种情况都可以跳跃着搜索,(在起跳点所在的这条对角线的向量上,对跳跃的落脚点进行二分)。

      这样总的情况其实是很少的,可以加一个记忆化

      (思路来源于 1,2,3

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <map>
    #include <vector>
    
    using namespace std;
    
    typedef long long ll;
    
    const int M=6e4+44;
    const int bas=M-22;
    
    int n,k;
    int A[M],B[M],plcb[M];
    map<int,map<int,int> > mp; //saves for case 1,case 2
    vector<int> dia[M*2]; //diagonals saves
    
    void init()
    {
    	mp.clear();
    	int i,j,valb,pb;
    	for(i=1-n;i<=n-1;i++)
    		dia[i+bas].clear();
    	for(i=1;i<=n;i++)
    		for(j=0;j<=k;j++)
    		{
    			valb=A[i]-j;
    			if(valb>0)
    			{
    				pb=plcb[valb];
    				dia[i-pb+bas].push_back(i);
    			}
    			valb=A[i]+j;
    			if(valb<=n)
    			{
    				pb=plcb[valb];
    				dia[i-pb+bas].push_back(i);
    			}
    		}
    	for(i=1-n;i<=n-1;i++)
    		sort(dia[i+bas].begin(),dia[i+bas].end());
    }
    
    int deal(int wh,int now)
    {
    	int i,j,li,ri,mid;
    	if(dia[wh].size()==0 || dia[wh][0]>now)
    		return now-min(now,now-(wh-bas));
    	li=0; ri=dia[wh].size();
    	while(li<ri-1)
    	{
    		mid=(li+ri)>>1;
    		if(dia[wh][mid]<now)
    			li=mid;
    		else
    			ri=mid;
    	}
    	return dia[wh][li];
    }
    
    int dfs(int x,int y)
    {
    	int i,j,tmp,ret,val1,val2;
    	if(x==0 || y==0)
    		return x+y;
    	if(abs(A[x]-B[y])<=k)
    	{
    		val1=mp[x-1][y];
    		if(val1==0) val1=dfs(x-1,y);
    		val2=mp[x][y-1];
    		if(val2==0) val2=dfs(x,y-1);
    		ret=1+min(val1,val2);
    		mp[x][y]=ret;
    		return ret;
    	}
    	else
    	{
    		tmp=x-deal(x-y+bas,x);
    		ret=tmp+dfs(x-tmp,y-tmp);
    		mp[x][y]=ret;
    		return ret;
    	}
    }
    
    int main()
    {
    //	freopen("数据\1010.in","r",stdin);
    //	freopen("数据\fxxl1010.out","w",stdout);
    	int i,j;
    	int cas;
    	scanf("%d",&cas);
    	while(cas--)
    	{
    		scanf("%d%d",&n,&k);
    		for(i=1;i<=n;i++)
    			scanf("%d",&A[i]);
    		for(i=1;i<=n;i++)
    		{
    			scanf("%d",&B[i]);
    			plcb[B[i]]=i;
    		}
    		init();
    		int ans=dfs(n,n);
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    表单提交时,更新的操作
    提交后刷新本页面与移除本页面的JS写法
    jquery的$.each如何退出循环和退出本次循环
    修改本机host文件,使upf报表操作变的快
    代码记录
    JQuery简介
    Ubuntu安装
    PHP笔记(PHP高级篇)
    将Session写入Memcache
    将Session写入数据库
  • 原文地址:https://www.cnblogs.com/FxxL/p/7301030.html
Copyright © 2020-2023  润新知