神坑的一道题,写了三遍。
两点半开始写的,
第一遍是直接维护两行的二进制。理论上是没问题的,看POJ discuss 上也有人实现了,但是我敲完后准备开始调了。然后就莫名其妙的以为会超时,就删掉了。
第二遍是想错了,因为和之前写过的一道题很像,那道题的正方形最中间不重合即可,所以我以为本质是一样的,然后按照那样的思路写。写写调调到五点半,样例搞掉后,提交,A2T7W1
然后随便找了组数组跟了一下,发现这个方块不允许重合导致这两道题的核心思路差别很大,所以删掉了。
第三遍开始按照自己想的3进制方案写,为了防止再次出现重新写一遍..先找山神问了一下可行性。然后就开始敲,到六点半敲完调完,在校内OJ上交又是各种WA各种TLE,遂弃疗回家,在POJ上看了看发现POJ上的每组数据给了5s,然后发现了几个傻逼错误,改了改终于A调了。
Run ID |
User |
Problem |
Result |
Memory |
Time |
Language |
Code Length |
Submit Time |
16006693 |
Cydiater |
1038 |
Accepted |
17160K |
11250MS |
G++ |
3288B |
2016-08-22 21:20:49 |
16006635 |
Cydiater |
1038 |
Wrong Answer |
G++ |
3290B |
2016-08-22 21:10:12 |
||
16006634 |
Cydiater |
1038 |
Wrong Answer |
C++ |
3290B |
2016-08-22 21:09:57 |
||
16006629 |
Cydiater |
1038 |
Wrong Answer |
C++ |
3290B |
2016-08-22 21:08:53 |
||
16006549 |
Cydiater |
1038 |
Wrong Answer |
C++ |
3290B |
2016-08-22 20:56:34 |
||
16006543 |
Cydiater |
1038 |
Memory Limit Exceeded |
C++ |
3290B |
2016-08-22 20:55:59 |
不要问我为什么前五次代码长度一摸一样==
不说废话,我说说我的想法,好像效率很低,但是比较好理解吧(至少我很好理解
基本的和普通的状压DP一样,一个线扫下来枚举状态。但是状态的表示用三进制表示用四进制处理,具体实现比较麻烦,可以参考代码。
0->未被覆盖
1->被覆盖
2->被覆盖且下方的方块也被覆盖
剩下的就很好搞了。
时间的话把枚举的状态改成堆或许会好点?
1 //OJ 1391 2 //by Cydiater 3 //2016.8.22 4 #include <iostream> 5 #include <cstring> 6 #include <string> 7 #include <cstdio> 8 #include <cstdlib> 9 #include <cmath> 10 #include <ctime> 11 #include <iomanip> 12 #include <queue> 13 #include <map> 14 #include <algorithm> 15 using namespace std; 16 #define ll long long 17 #define up(i,j,n) for(ll i=j;i<=n;i++) 18 #define down(i,j,n) for(ll i=j;i>=n;i--) 19 const int MAXN=1<<20; 20 const int oo=0x3f3f3f3f; 21 inline ll read(){ 22 char ch=getchar();ll x=0,f=1; 23 while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘)f=-1;ch=getchar();} 24 while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} 25 return x*f; 26 } 27 ll N,M,K,f[2][MAXN],ans=0,T; 28 bool flag[155][155]; 29 namespace solution{ 30 void print(ll s){ 31 ll a[25]; 32 memset(a,0,sizeof(a)); 33 down(i,M,1){ 34 a[i]=s%4; 35 s/=4; 36 } 37 up(i,1,M)cout<<a[i];; 38 puts(""); 39 } 40 inline ll get(ll s,ll pos){ 41 pos=M-pos-1; 42 ll tmp=s&(3<<(pos<<1)); 43 tmp>>=(pos<<1); 44 return tmp; 45 } 46 inline ll updata(ll s,ll st,ll nd,ll num){ 47 ll ss=st,n=nd; 48 st=M-n-1;nd=M-ss-1; 49 up(i,st,nd)s|=(num<<(i<<1)); 50 return s; 51 } 52 void init(){ 53 memset(f,0,sizeof(f)); 54 memset(flag,0,sizeof(flag)); 55 N=read();M=read();K=read(); 56 ans=0; 57 up(i,1,K){ 58 ll x=read(),y=read()-1; 59 flag[x][y]=1; 60 } 61 } 62 bool check(ll x,ll st,ll nd,ll s){ 63 if(st<0||st>=M||nd<0||nd>=M||x<=0||x>N) return 0; 64 up(i,st,nd)if(flag[x][i]) return 0;/*special case*/ 65 up(i,st,nd)if(get(s,i)!=0) return 0; 66 return 1; 67 } 68 void dfs(ll x,ll y,ll s,ll now,ll k){ 69 if(y<0){ 70 f[x%2][now]=max(f[x%2][now],f[(x%2)^1][s]+k); 71 ans=max(ans,f[x%2][now]); 72 /*puts("s:");print(s);puts("now:");print(now); 73 printf("x:%d f[x%%2][now]:%d ",x,f[x%2][now]); 74 cout<<"k:"<<k<<" ans:"<<ans<<endl<<endl;*/ 75 return; 76 } 77 //cout<<now<<endl; 78 if(get(s,y)==2){ 79 now|=(1<<((M-y-1)<<1)); 80 dfs(x,y-1,s,now,k); 81 return; 82 } 83 if(check(x-1,y-1,y+1,s)/* <- check last status*/&&check(x,y-1,y+1,now)/*<- check now status*/)dfs(x,y-1,s,updata(now,y-1,y+1,1),k+1); 84 if(check(x-1,y,y+1,s)/*<- check last status*/&&check(x,y,y+1,now)/*<- check now status*/&&!flag[x+1][y]&&!flag[x+1][y+1]&&x+1<=N/*check next set*/)dfs(x,y-1,s,updata(now,y,y+1,2),k+1); 85 dfs(x,y-1,s,now,k); 86 } 87 void dp(){ 88 f[0][0]=1; 89 up(i,0,N){ 90 up(s,0,(1<<(M<<1))-1)f[(i%2)^1][s]=0; 91 up(s,0,(1<<(M<<1))-1)if(f[i%2][s]>0)dfs(i+1,M-1,s,0,0); 92 } 93 } 94 void output(){ 95 cout<<ans-1<<endl; 96 } 97 } 98 int main(){ 99 //freopen("input.in","r",stdin); 100 //freopen("output.out","w",stdout); 101 using namespace solution; 102 T=read(); 103 while(T--){ 104 init(); 105 dp(); 106 output(); 107 } 108 return 0; 109 }
时间: 2024-10-07 00:01:39