hdu 5031 Lines
2014-11-19 16:38
267 查看
DFS暴力剪枝2014广州网络赛的J题,
太恶心了,大模拟,狂搜索
Orz...............
注意最优化剪枝。
对于一个点,搜索时(此点必定是直线的起点,否则会数重的),先判断水平和竖直能不能划线(注意不要数重,当i==1 || j==1时才能竖直水平化);在枚举在此点下面的点,合法性剪枝,点数要大于3.
狠黄狠暴力。
输入输出优化 + G++交的,982ms
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #define inf 1000000000 using namespace std; typedef long long ll; void in(int &x){ char ch; int minus = 0; while (ch=getchar(), (ch<'0'||ch>'9') && ch!='-'); if (ch == '-') minus = 1, x = 0; else x = ch-'0'; while (ch=getchar(), ch>='0'&&ch<='9') x = x*10+ch-'0'; if (minus) x = -x; } void in(ll &x){ char ch; int minus = 0; while (ch=getchar(), (ch<'0'||ch>'9') && ch!='-'); if (ch == '-') minus = 1, x = 0; else x = ch-'0'; while (ch=getchar(), ch>='0'&&ch<='9') x = x*10+ch-'0'; if (minus) x = -x; } void out(int x){ char hc[30];int len, minus=0; if (x<0) minus = 1, x = -x; len = 0; hc[len++] = x%10+'0'; while (x/=10) hc[len++] = x%10+'0'; if (minus) putchar('-'); for (int i=len-1; i>=0; i--) putchar(hc[i]); } void out(ll x){ char hc[30];int len, minus=0; if (x<0) minus = 1, x = -x; len = 0; hc[len++] = x%10+'0'; while (x/=10) hc[len++] = x%10+'0'; if (minus) putchar('-'); for (int i=len-1; i>=0; i--) putchar(hc[i]); } const int N = 50+10; int a ; int n,m; int sum; int ans; int isin(int x,int y) { if(x>=1 && x<=n && y>=1 && y<=m) return 1; return 0; } void dfs(int now,int re) { if(now>=ans) return ; if(re==0) { //printf("geng xi %d\n",now); ans = min(ans,now); return ; } int cnt = 0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cnt = max(cnt,a[i][j]); if(now + cnt >=ans) return ; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(a[i][j]) { int fl=1,fll=1; if(i==1){ for(int k=1;k<=n;k++) if(!a[k][j]) {fl=0;break;} if(fl) { for(int k=1;k<=n;k++) a[k][j]--; dfs(now+1,re-n); for(int k=1;k<=n;k++) a[k][j]++; } } if(j==1){ for(int k=1;k<=m;k++) if(!a[i][k]) {fll=0;break;} if(fll) { for(int k=1;k<=m;k++) a[i][k]--; dfs(now+1,re-m); for(int k=1;k<=m;k++) a[i][k]++; } } for(int ii=i+1;ii<=n;ii++) { for(int jj=1;jj<=m;jj++) { if(!a[i][j]) break; if(!a[ii][jj]) continue; if(ii==i || jj==j) continue; int dx = ii-i,dy=jj-j; int tx=i,ty=j; int cn=0,flag=1; while(1) { if(!isin(tx,ty)) break; if(!a[tx][ty]) {flag=0;break;} cn++; tx+=dx; ty+=dy; } tx=i-dx,ty=j-dy; if(isin(tx,ty)) flag=0; if(flag==0) continue; if(cn<3) continue; tx=i,ty=j; while(1) { if(!isin(tx,ty)) break; a[tx][ty]--; tx+=dx; ty+=dy; } //printf("直线 %d,%d --- %d,%d cut = %d , now = %d ,re = %d\n",i,j,ii,jj,cn,now+1,re-cn); dfs(now+1,re-cn); tx=i,ty=j; while(1) { if(!isin(tx,ty)) break; a[tx][ty]++; tx+=dx; ty+=dy; } } } return ; } } } } int main() { int t; in(t); while(t--) { sum=0; ans = inf; in(n);in(m); n++;m++; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { in(a[i][j]); sum+=a[i][j]; } ans = min(14,sum/3); dfs(0,sum); out(ans); putchar('\n'); } return 0; }
相关文章推荐
- hdu 5031 Lines 爆搜
- HDU-5031-Lines(DFS)
- hdu 5031 Lines 爆搜
- HDU lines && TIANKENG’s restaurant
- HDU 5124 lines 最多区间覆盖
- hdu 5124——lines
- HDU - 5124 lines
- 【HDU - 5124】 lines 【树状数组+离散化】
- HDOJ 5031 Lines
- [思路题] hdu 5124 lines
- BestCoder20 1002.lines (hdu 5124) 解题报告
- 【扫描线】HDU 5124 lines
- HDU 5124 lines
- HDU 5124 lines
- HDU 5124 lines
- hdu 5124 lines(树状数组)
- hdu 5124 BestCoder #20 1002 lines 解题报告
- hdu 5124 lines (线段树+离散化)
- HDU 5124 lines
- HDU 5031:看脸的DFS