• CF1427C Solution


    题目链接

    题解

    这道题\(10^5\)的数据范围显然不可以用图论,因此是贪心和dp中的一种,可是在单个子问题中最优的方案不一定满足全局最优,所以只能用dp。

    \(dp[i]\)表示前\(i\)个人中可以拍下的最大人数(必须选择第\(i\)个人)。转移则在所有可以到达\(i\)的点中选取\(dp\)值最大即可,转移方程:\(dp[i]=max(dp[i],dp[j]+1)\quad\quad (0\le j<i,dis(i,j)<=t[i]-t[j] )\)

    显然,这个方程的时间复杂度为\(O(n^2)\),会超时。观察这个\(r\cdot r\)的网格图,可以发现从一个点到另一个点的最长路径为\(2r-2\)(从\((1,1)\)\((r,r)\))。所以我们只用枚举\(t[i]-t[j]<2r-2\)\(j\),再之前的\(j\)一定可以到达\(i\)。另设\(ans[j]\)记录前\(j\)人可以不选第\(j\)个人时的最大\(dp\)值,便可\(O(1)\)求出满足\(t[i]-t[j]>=2r-2\)\(j\)的最大值。

    AC代码

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+10;
    int x[N],y[N],t[N],dp[N],ans[N];
    int main()
    {
    	int r,n;
    	scanf("%d%d",&r,&n);
    	for(int i=1;i<=n;i++) scanf("%d%d%d",&t[i],&x[i],&y[i]);
    	memset(dp,-0x3f,sizeof(dp));
    	t[0]=0,x[0]=1,y[0]=1,dp[0]=0,ans[0]=0;
    	for(int i=1;i<=n;i++)
    	{
    		int j;
    		for(j=i-1;j>=0;j--)
    		{
    			if(t[i]-t[j]>=(2*r-2)) break;
    			if(abs(x[i]-x[j])+abs(y[i]-y[j])<=t[i]-t[j]) dp[i]=max(dp[i],dp[j]+1);
    		} 
    		if(j>=0) dp[i]=max(dp[i],ans[j]+1); 
    		ans[i]=max(ans[i-1],dp[i]);
    	}
    	printf("%d",ans[n]);
    	return 0;
    }
    
  • 相关阅读:
    leetcode[45]Jump Game II
    leetcode[46]Permutations
    leetcode[47]Permutations II
    leetcode[48]Rotate Image
    手把手一起玩perl安装
    List the Modules in Your System
    oracle之recyclebin
    10g 11g新特性
    RMAN相关操作命令
    手把手一起安装RAC+DataGuard
  • 原文地址:https://www.cnblogs.com/violetholmes/p/14162842.html
Copyright © 2020-2023  润新知