• LightOJ1018 Brush (IV)(状压DP)


    题目大概说一个平面有n个灰尘,可以用一把刷子直直刷过去清理直线上的所有灰尘,问最少要刷几下才能清理完所有灰尘。

    • 首先怎么刷其实是可以确定的,或者说直线有哪些是可以确定的,而最多就有C(n,2)条不一样的直线,即16*15/2=120;
    • 然后容易想到用状压DP求解,d[S]表示已经清理的灰尘的状态是S最少刷的次数;
    • 而转移就是通过枚举接下来使用那条直线,用我为人人的方式转移,
    • 另外直线包含的灰尘集合状态一开始就可以预处理出来,这样时间复杂度O(2n*n2)。

    不过超时,超了800多ms。实在想不出怎么没办法。而看了网上,也是一样思路,不过转移是任意选出一个没有在S中的点,然后枚举另一个没有在S的端点,通过添加这两点构成的直线去转移,时间复杂度O(2n*n)。

    我表示不解。。这样有些状态会漏吧???

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 
     6 int d[1<<16],sta[16][16];
     7 int main(){
     8     int t,n,x[16],y[16];
     9     scanf("%d",&t);
    10     for(int cse=1; cse<=t; ++cse){
    11         scanf("%d",&n);
    12         for(int i=0; i<n; ++i){
    13             scanf("%d%d",x+i,y+i);
    14         }
    15         if(n==1){
    16             printf("Case %d: %d
    ",cse,1);
    17             continue;
    18         }
    19         for(int i=0; i<n; ++i){
    20             for(int j=0; j<n; ++j){
    21                 if(i==j){
    22                     sta[i][j]=(1<<i);
    23                     continue;
    24                 }
    25                 int s=0;
    26                 for(int k=0; k<n; ++k){
    27                     if((x[i]-x[j])*(y[j]-y[k])==(x[j]-x[k])*(y[i]-y[j])){
    28                         s|=(1<<k);
    29                     }
    30                 }
    31                 sta[i][j]=s;
    32             }
    33         }
    34         memset(d,127,sizeof(d));
    35         d[0]=0;
    36         for(int i=0; i<(1<<n)-1; ++i){
    37             if(d[i]>10000) continue;
    38             int j=0;
    39             while(j<n){
    40                 if((i>>j&1)==0) break;
    41                 ++j;
    42             }
    43             for(int k=0; k<n; ++k){
    44                 if((i>>k&1)==0){
    45                     d[i|sta[j][k]]=min(d[i|sta[j][k]],d[i]+1);
    46                 }
    47             }
    48         }
    49         printf("Case %d: %d
    ",cse,d[(1<<n)-1]);
    50     }
    51     return 0;
    52 }
  • 相关阅读:
    微访谈之1:解答各位朋友关心的问题
    深入浅出SQL Server中的死锁(实战篇)
    怎样玩转千万级别的数据
    Another MySQL daemon already running with the same unix socket
    c++ undefined reference to mysqlinit
    Another MySQL daemon already running with the same unix socket
    linxu 挂载分区
    C# RSA
    谷歌地图实现车辆轨迹移动播放(google map api)
    百度地图实现车辆轨迹移动播放(baidu map api)
  • 原文地址:https://www.cnblogs.com/WABoss/p/5657764.html
Copyright © 2020-2023  润新知