POJ 1038 Bugs Integrated, Inc.

AC通道

神坑的一道题,写了三遍。

两点半开始写的,

第一遍是直接维护两行的二进制。理论上是没问题的,看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-08-02 14:27:10

POJ 1038 Bugs Integrated, Inc.的相关文章

POJ 1038 Bugs Integrated, Inc. 状态压缩DP

题目来源:1038 Bugs Integrated, Inc. 题意:最多能放多少个2*3的矩形 思路:状态压缩DP啊 初学 看着大牛的代码搞下来的  总算搞懂了 接下来会更轻松吧 3进制代表前2行的状态(i行和i-1行)1代表i-1行占位 2代表i行占位 i-1不管有没有占位都不会影响的0代表i行和i-1行都空闲 然后枚举状态dfs更新状态 话说就不能没写深搜了 有点不会了 #include <cstdio> #include <cstring> #include <alg

POJ 1038 Bugs Integrated Inc (复杂的状压DP)

\(POJ~1038~~*Bugs~Integrated~Inc:\) (复杂的状压DP) \(solution:\) 很纠结的一道题目,写了大半天,就想练练手,结果这手生的.其实根据之前那道炮兵阵地就不应该写的,但是总觉得自己的思路会好一些,码量又小. 博主的核心思路其实就是用一个二进制数来压缩三行的状态,因为二进制的左移右移很方便.然后就是如果三进制会很不好转移. 我们可以用一个二进制数来预处理压缩出第 \(i\) 往下三行的障碍状态,前 \(m\) 个二进制位表第 \(i\) 行,中间 \

POJ 1038 Bugs Integrated, Inc.(状态压缩)

Bugs Integrated, Inc. Time Limit: 15000MS   Memory Limit: 30000K Total Submissions: 9088   Accepted: 3472 Case Time Limit: 5000MS Description Bugs Integrated, Inc. is a major manufacturer of advanced memory chips. They are launching production of a n

POJ 1038 Bugs Integrated, Inc. ——状压DP

状压上面有几个方块,然后DFS转移. 复杂度貌似很高$3_{}^{20}*n$ 反正过了 #include <map> #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define F(i,j,k) for (int i=j;i<=k;++i)

CEOI 2002, POJ 1038 Bugs Integrated, Inc. 状态压缩 DP

有点点小虐心. #include <iostream> #include <cstring> #include <fstream> using namespace std; const int ternarys[12] = { 0, 1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683, 59049 }; int DP[2][59049]; int bit_map[155][15]; int pre_line[15]; int now

POJ 1038 状压DP

一个公司生产一种2*3规模的芯片,但是原材料上面有一些地方是不能用来当作芯片材料的,给出原料大小,及上面不能做原料的点,问你怎么分解,可以使生成芯片最大化. 对M进行三进制状压 last数组存储第i-1行和i-2行状态,cur数组存储i行和i-1行状态 cur[k]=2; // 本行k位置和上行k位置都不可用 cur[k]=1; // 本行k位置可用,上行k位置不可用 cur[k]=0; // 本行和上行位置k均可用 必须用滚动数组,否则爆内存 #include "stdio.h" #

poj1038 Bugs Integrated, Inc.

二进制状压练得挺熟, 但是一直没有时间好好研究三进制状压. 于是找了个题目学习了一下, 两天里修修补补总算AC了. 有几个收获. 1. 三进制与十进制的转换的小技巧(利用数组) 2. 刷表法时, 用dfs来更新状态.这种更新状态的方式蛮新颖的,我这种蒟蒻第一次遇见. 3. 还是更新状态.可以先把新状态算出来,再来枚举决策. #include <cstdio> #include <cstring> #include <iostream> #include <algo

ACM训练方案-POJ题目分类

ACM训练方案-POJ题目分类 博客分类: 算法 ACM online Judge 中国: 浙江大学(ZJU):http://acm.zju.edu.cn/ 北京大学(PKU):http://acm.pku.edu.cn/JudgeOnline/ 杭州电子科技大学(HDU):http://acm.hdu.edu.cn/ 中国科技大学(USTC):http://acm.ustc.edu.cn/ 北京航天航空大学(BUAA)http://acm.buaa.edu.cn/oj/index.php 南京

转载:poj题目分类(侵删)

转载:from: POJ:http://blog.csdn.net/qq_28236309/article/details/47818407 按照ac的代码长度分类(主要参考最短代码和自己写的代码) 短代码:0.01K–0.50K:中短代码:0.51K–1.00K:中等代码量:1.01K–2.00K:长代码:2.01K以上. 短:1147.1163.1922.2211.2215.2229.2232.2234.2242.2245.2262.2301.2309.2313.2334.2346.2348