zoukankan      html  css  js  c++  java
  • JXOI2018 守卫

    传送门

    听说这题误导性很强……我倒没有…… 我只是单纯的不知道怎么做……
    实际上很简单。考虑到最右面是必须放守卫的,我们从右边开始DP,设(dp[l][r])表示区间([l,r])需要摆放的最小守卫数,p表示能观察到的最远的亭子,那么有(dp[l][r] = sum + min(dp[l][p],dp[l][p-1])),因为你在p或者p-1必须要放一个。
    sum的更新是每次如果p被更新的话,那么(sum += min(dp[l][p],dp[l][p-1]))

    然后我们这样从左往右枚举右端点,然后对于每个右端点倒着DP回去就行了。顺便亦或一下答案。

    #include<bits/stdc++.h>
    #define rep(i,a,n) for(int i = a;i <= n;i++)
    #define per(i,n,a) for(int i = n;i >= a;i--)
    #define enter putchar('
    ')
    #define pr pair<int,int>
    #define mp make_pair
    #define fi first
    #define sc second
    using namespace std;
    typedef long long ll;
    const int M = 5005;
    const int N = 10000005;
     
    int read()
    {
       int ans = 0,op = 1;char ch = getchar();
       while(ch < '0' || ch > '9') {if(ch == '-') op = -1;ch = getchar();}
       while(ch >='0' && ch <= '9') ans = ans * 10 + ch - '0',ch = getchar();
       return ans * op;
    }
    
    struct dot
    {
       double x,y;
    }a[M];
    double slope(int f,int g){return (a[g].y - a[f].y) / (a[g].x - a[f].x);}
    int n,dp[M][M],ans,sum,p;
    
    int main()
    {
       n = read();
       rep(i,1,n) a[i].x = i,scanf("%lf",&a[i].y);
       rep(r,1,n)
       {
          dp[r][r] = 1,sum = 1,p = 0;
          per(l,r-1,1)
          {
    	 if(!p || slope(l,r) < slope(p,r)) sum += min(dp[l+1][p],dp[l+1][p-1]),p = l;
    	 dp[l][r] = sum + min(dp[l][p],dp[l][p-1]);
          }
       }
       rep(i,1,n)rep(j,1,i) ans ^= dp[j][i];
       printf("%d
    ",ans);
       return 0;
    }
    
    
  • 相关阅读:
    DNS域名解析中A、AAAA、CNAME、MX、NS、TXT、SRV、SOA、PTR各项记录的作用
    HTTP数据包
    渗透——网络基础
    渗透——linux基础
    渗透——http协议基础
    渗透——CMS基础
    渗透测试流程
    渗透专用术语
    CodeFoeces GYM 101466A Gaby And Addition (字典树)
    关于Windows10内存随时间不断升高问题
  • 原文地址:https://www.cnblogs.com/captain1/p/10596840.html
Copyright © 2011-2022 走看看