zoukankan      html  css  js  c++  java
  • Codeforces Round #622 (Div. 2)D(离散化,状压DP)

     1 #define HAVE_STRUCT_TIMESPEC
     2 #include<bits/stdc++.h>
     3 using namespace std;
     4 int bit[1<<9];
     5 set<int>s;
     6 pair<int,int>a[200007];
     7 int pre[10];
     8 int dp[1<<9];
     9 int pos[200007];
    10 int main(){
    11     ios::sync_with_stdio(false);
    12     cin.tie(NULL);
    13     cout.tie(NULL);
    14     int n,m,k;
    15     cin>>n>>m>>k;
    16     for(int i=1;i<=n;++i){
    17         int x,y;
    18         cin>>x>>y;
    19         a[2*i-1]={x,i};//记录线段端点位置
    20         a[2*i]={y+1,-i};//前缀相减,故存右端点时+1
    21     }
    22     for(int i=0;i<=k;++i)
    23         pre[i]=1<<i;//二进制下第i位为1的数字大小
    24     for(int i=1;i<pre[k];++i){
    25         bit[i]=bit[i>>1]^(i&1);//把i在二进制下为1的个数为奇数的bit[i]变为1
    26         dp[i]=-1e9;
    27     }
    28     sort(a+1,a+1+2*n);
    29     int last=0;//前一个端点位置
    30     for(int i=0;i<k;++i)
    31         s.insert(i);//每条线段给一个编号
    32     for(int i=1;i<=2*n;++i){
    33         int now=a[i].first;
    34         int temp=a[i].second;
    35         for(int j=1;j<pre[k];++j)
    36             dp[j]+=bit[j]*(now-last);//当前情况下线段数为奇数的可以加上这一段线段的长度
    37         last=now;//这个端点用过了,记下他的位置
    38         if(temp>0){//这个端点是左端点
    39             pos[temp]=*s.begin();//去集合里领取一条线段的编号,记作当前线段的编号
    40             s.erase(pos[temp]);
    41             for(int j=0;j<pre[k];++j)//枚举所有情况
    42                 if(j&pre[pos[temp]])//包含这条线段的情况
    43                     dp[j]=max(dp[j],dp[j^pre[pos[temp]]]);//更新最大值
    44         }
    45         else{//这个端点是右端点
    46             temp=-temp;
    47             s.insert(pos[temp]);//这条线段用完了还给集合
    48             for(int j=0;j<pre[k];++j)//枚举所有情况
    49                 if(j&pre[pos[temp]]){//包含这条线段的情况
    50                     dp[j^pre[pos[temp]]]=max(dp[j^pre[pos[temp]]],dp[j]);//更新最大值
    51                     dp[j]=-1e9;//这条线段不取,包含这条线段的情况初始化
    52                 }
    53         }
    54     }
    55     cout<<dp[0];//所有线段都遍历一遍以后,所有线段都不取,dp[0]为扫过一遍的答案
    56     return 0;
    57 }
  • 相关阅读:
    VMWare ESX Server
    ubuntu 13.04 xrdp 远程桌面连接问题[转载]
    wget 使用技巧
    C# 跨线程调用问题
    ASP.NET WEB API 返回JSON 出现2个双引号问题
    ASP.NET MVC 4 中Razor 视图中JS无法调试
    Android 如何修改gen下包的名字
    打开AVD时报”Data partition already in use. Changes will not persist!”
    Android 将APK文件安装到AVD中并分析其界面结构
    Android 实现界面(Activity)的跳转
  • 原文地址:https://www.cnblogs.com/ldudxy/p/12397910.html
Copyright © 2011-2022 走看看