hdu4539 郑厂长系列故事——排兵布阵 + POJ1158 炮兵阵地
生活随笔
收集整理的這篇文章主要介紹了
hdu4539 郑厂长系列故事——排兵布阵 + POJ1158 炮兵阵地
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
題意:
? ? ? ? ? ? ? ? ?鄭廠長(zhǎng)系列故事——排兵布陣
Time Limit: 10000/5000 MS (Java/Others) ? ?Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 1883 ? ?Accepted Submission(s): 686
Problem Description
鄭廠長(zhǎng)不是正廠長(zhǎng)
也不是副廠長(zhǎng)
他根本就不是廠長(zhǎng)
事實(shí)上
他是帶兵打仗的團(tuán)長(zhǎng)
一天,鄭廠長(zhǎng)帶著他的軍隊(duì)來(lái)到了一個(gè)n*m的平原準(zhǔn)備布陣。
根據(jù)以往的戰(zhàn)斗經(jīng)驗(yàn),每個(gè)士兵可以攻擊到并且只能攻擊到與之曼哈頓距離為2的位置以及士兵本身所在的位置。當(dāng)然,一個(gè)士兵不能站在另外一個(gè)士兵所能攻擊到的位置,同時(shí)因?yàn)榈匦蔚脑蚱皆弦膊皇敲恳粋€(gè)位置都可以安排士兵。
現(xiàn)在,已知n,m 以及平原陣地的具體地形,請(qǐng)你幫助鄭廠長(zhǎng)計(jì)算該陣地,最多能安排多少個(gè)士兵。
?
Input
輸入包含多組測(cè)試數(shù)據(jù);
每組數(shù)據(jù)的第一行包含2個(gè)整數(shù)n和m (n <= 100, m <= 10 ),之間用空格隔開(kāi);
接下來(lái)的n行,每行m個(gè)數(shù),表示n*m的矩形陣地,其中1表示該位置可以安排士兵,0表示該地形不允許安排士兵。
?
Output
請(qǐng)為每組數(shù)據(jù)計(jì)算并輸出最多能安排的士兵數(shù)量,每組數(shù)據(jù)輸出一行。
?
Sample Input
6 6
0 0 0 0 0 0
0 0 0 0 0 0
0 0 1 1 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
?
Sample Output
2
思路:
? ? ? 說(shuō)好了狀態(tài)壓縮dp的,自己dp寫(xiě)著特別費(fèi)勁,寫(xiě)了一個(gè),結(jié)果超時(shí)了,然后果斷換思路,后來(lái)感覺(jué)可以直接求最大獨(dú)立集,因?yàn)椴荒艹橄竽芏謭D,所以如果想求獨(dú)立集,那么就只剩下一個(gè)比較暴力的np問(wèn)題了,就是最大團(tuán),雖說(shuō)是np問(wèn)題,但是可以靠一些很實(shí)用的剪紙和簡(jiǎn)單dp來(lái)優(yōu)化,這個(gè)題目還是輕松的過(guò)掉了,建圖的時(shí)候把不沖突的兩個(gè)點(diǎn)連接起來(lái),最后一遍最大團(tuán)就行了。同樣的還有POJ1185 炮兵陣地,只是建圖的時(shí)候的限制不一樣而已,別的都一樣,具體看代碼,明明是在學(xué)習(xí)dp,怎么又寫(xiě)圖論了。
#include<stdio.h>
#include<string.h>
#define N 1100
typedef struct
{
? ?int x ,y;
}NODE;
NODE node[N];
int map[N][N] ,n;
int dp[N] ,now[N];
int Ans;
void DFS(int s ,int sum)
{
? ?if(Ans < sum) ?Ans = sum;
? ?int tnow[N] ,able = 0;
? ?for(int i = s + 1 ;i <= n ;i ++)
? ?{
? ? ? tnow[i] = now[i];
? ? ? if(now[i]) able ++;
? ?}
? ?if(able + sum < Ans) return;
? ?for(int i = s + 1 ;i <= n ;i ++)
? ?{
? ? ? if(!tnow[i]) continue;
? ? ? if(sum + dp[i] <= Ans) return;
? ? ? for(int j = s+1 ;j <= n ;j ++)
? ? ? now[j] = tnow[j] & map[i][j];
? ? ? DFS(i ,sum + 1);
? ?}
}
int Max_Tuan()
{
? ?dp[n] = Ans = 1;
? ?for(int i = n - 1 ;i >= 1 ;i --)
? ?{
? ? ? for(int j = 1 ;j <= n ;j ++)
? ? ? now[j] = map[i][j];
? ? ? now[i] = 1;
? ? ? DFS(i ,1);
? ? ? dp[i] = Ans;
? ?}
? ?return Ans;
}
int abss(int x)
{
? ?return x > 0 ? x : -x;
}
int ok(int a ,int b)
{
? ?int dis = abss(node[a].x - node[b].x) + abss(node[a].y - node[b].y);
? ?if(dis == 2) return 0;
? ?return 1;
}
int main ()
{
? ?int nn ,mm ,i ,j ,a;
? ?while(~scanf("%d %d" ,&nn ,&mm))
? ?{
? ? ? int nowid = 0;
? ? ? for(i = 1 ;i <= nn ;i ++)
? ? ? for(j = 1 ;j <= mm ;j ++)
? ? ? {
? ? ? ? ?scanf("%d" ,&a);
? ? ? ? ?if(!a) continue;
? ? ? ? ?nowid ++;
? ? ? ? ?node[nowid].x = i ,node[nowid].y = j;
? ? ? }
? ? ? if(!nowid)
? ? ? {
? ? ? ? ?printf("0\n");
? ? ? ? ?continue;
? ? ? }
? ? ? memset(map ,0 ,sizeof(map));
? ? ? for(i = 1 ;i <= nowid ;i ++)
? ? ? for(j = i + 1 ;j <= nowid ;j ++)
? ? ? map[i][j] = map[j][i] = ok(i ,j);
? ? ? n = nowid;
? ? ? printf("%d\n" ,Max_Tuan());
? ?}
? ?return 0;
}
POJ 1185
炮兵陣地
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 19703 Accepted: 7610
Description
司令部的將軍們打算在N*M的網(wǎng)格地圖上部署他們的炮兵部隊(duì)。一個(gè)N*M的地圖由N行M列組成,地圖的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示),如下圖。在每一格平原地形上最多可以布置一支炮兵部隊(duì)(山地上不能夠部署炮兵部隊(duì));一支炮兵部隊(duì)在地圖上的攻擊范圍如圖中黑色區(qū)域所示:?
如果在地圖中的灰色所標(biāo)識(shí)的平原上部署一支炮兵部隊(duì),則圖中的黑色的網(wǎng)格表示它能夠攻擊到的區(qū)域:沿橫向左右各兩格,沿縱向上下各兩格。圖上其它白色網(wǎng)格均攻擊不到。從圖上可見(jiàn)炮兵的攻擊范圍不受地形的影響。?
現(xiàn)在,將軍們規(guī)劃如何部署炮兵部隊(duì),在防止誤傷的前提下(保證任何兩支炮兵部隊(duì)之間不能互相攻擊,即任何一支炮兵部隊(duì)都不在其他支炮兵部隊(duì)的攻擊范圍內(nèi)),在整個(gè)地圖區(qū)域內(nèi)最多能夠擺放多少我軍的炮兵部隊(duì)。?
Input
第一行包含兩個(gè)由空格分割開(kāi)的正整數(shù),分別表示N和M;?
接下來(lái)的N行,每一行含有連續(xù)的M個(gè)字符('P'或者'H'),中間沒(méi)有空格。按順序表示地圖中每一行的數(shù)據(jù)。N <= 100;M <= 10。
Output
僅一行,包含一個(gè)整數(shù)K,表示最多能擺放的炮兵部隊(duì)的數(shù)量。
Sample Input
5 4
PHPP
PPHH
PPPP
PHPP
PHHP
Sample Output
6
Source
? ??
#include<stdio.h>
#include<string.h>
#define N 1100
typedef struct
{
? ?int x ,y;
}NODE;
NODE node[N];
int map[N][N] ,n;
int dp[N] ,now[N];
int Ans;
void DFS(int s ,int sum)
{
? ?if(Ans < sum) ?Ans = sum;
? ?int tnow[N] ,able = 0;
? ?for(int i = s + 1 ;i <= n ;i ++)
? ?{
? ? ? tnow[i] = now[i];
? ? ? if(now[i]) able ++;
? ?}
? ?if(able + sum < Ans) return;
? ?for(int i = s + 1 ;i <= n ;i ++)
? ?{
? ? ? if(!tnow[i]) continue;
? ? ? if(sum + dp[i] <= Ans) return;
? ? ? for(int j = s+1 ;j <= n ;j ++)
? ? ? now[j] = tnow[j] & map[i][j];
? ? ? DFS(i ,sum + 1);
? ?}
}
int Max_Tuan()
{
? ?dp[n] = Ans = 1;
? ?for(int i = n - 1 ;i >= 1 ;i --)
? ?{
? ? ? for(int j = 1 ;j <= n ;j ++)
? ? ? now[j] = map[i][j];
? ? ? now[i] = 1;
? ? ? DFS(i ,1);
? ? ? dp[i] = Ans;
? ?}
? ?return Ans;
}
int abss(int x)
{
? ?return x > 0 ? x : -x;
}
int ok(int a ,int b)
{
? ? int xx = abss(node[a].x - node[b].x);
? ? int yy = abss(node[a].y - node[b].y);
? ? if(!xx && yy <= 2 || !yy && xx <= 2) return 0;
? ? return 1;
}
int main ()
{
? ?int nn ,mm ,i ,j ,a;
? ?char str[110];
? ?while(~scanf("%d %d" ,&nn ,&mm))
? ?{
? ? ? int nowid = 0;
? ? ? for(i = 1 ;i <= nn ;i ++) ?
? ? ? {
? ? ? ? ?scanf("%s" ,str);?
? ? ? ? ?for(j = 1 ;j <= mm ;j ++)
? ? ? ? ?{
? ? ? ? ? ?
? ? ? ? ? ? if(str[j-1] != 'P') continue;
? ? ? ? ? ? nowid ++;
? ? ? ? ? ? node[nowid].x = i ,node[nowid].y = j;
? ? ? ? ?}
? ? ? }
? ? ? if(!nowid)
? ? ? {
? ? ? ? ?printf("0\n");
? ? ? ? ?continue;
? ? ? }
? ? ? memset(map ,0 ,sizeof(map));
? ? ? for(i = 1 ;i <= nowid ;i ++)
? ? ? for(j = i + 1 ;j <= nowid ;j ++)
? ? ? map[i][j] = map[j][i] = ok(i ,j);
? ? ? n = nowid;
? ? ? printf("%d\n" ,Max_Tuan());
? ?}
? ?return 0;
}
? ??
? ??
??
? ? ??
? ? ??
? ? ? ? ?
? ?
? ? ??
? ? ??
? ? ? ? ? ? ? ? ?鄭廠長(zhǎng)系列故事——排兵布陣
Time Limit: 10000/5000 MS (Java/Others) ? ?Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 1883 ? ?Accepted Submission(s): 686
Problem Description
鄭廠長(zhǎng)不是正廠長(zhǎng)
也不是副廠長(zhǎng)
他根本就不是廠長(zhǎng)
事實(shí)上
他是帶兵打仗的團(tuán)長(zhǎng)
一天,鄭廠長(zhǎng)帶著他的軍隊(duì)來(lái)到了一個(gè)n*m的平原準(zhǔn)備布陣。
根據(jù)以往的戰(zhàn)斗經(jīng)驗(yàn),每個(gè)士兵可以攻擊到并且只能攻擊到與之曼哈頓距離為2的位置以及士兵本身所在的位置。當(dāng)然,一個(gè)士兵不能站在另外一個(gè)士兵所能攻擊到的位置,同時(shí)因?yàn)榈匦蔚脑蚱皆弦膊皇敲恳粋€(gè)位置都可以安排士兵。
現(xiàn)在,已知n,m 以及平原陣地的具體地形,請(qǐng)你幫助鄭廠長(zhǎng)計(jì)算該陣地,最多能安排多少個(gè)士兵。
?
Input
輸入包含多組測(cè)試數(shù)據(jù);
每組數(shù)據(jù)的第一行包含2個(gè)整數(shù)n和m (n <= 100, m <= 10 ),之間用空格隔開(kāi);
接下來(lái)的n行,每行m個(gè)數(shù),表示n*m的矩形陣地,其中1表示該位置可以安排士兵,0表示該地形不允許安排士兵。
?
Output
請(qǐng)為每組數(shù)據(jù)計(jì)算并輸出最多能安排的士兵數(shù)量,每組數(shù)據(jù)輸出一行。
?
Sample Input
6 6
0 0 0 0 0 0
0 0 0 0 0 0
0 0 1 1 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
?
Sample Output
2
思路:
? ? ? 說(shuō)好了狀態(tài)壓縮dp的,自己dp寫(xiě)著特別費(fèi)勁,寫(xiě)了一個(gè),結(jié)果超時(shí)了,然后果斷換思路,后來(lái)感覺(jué)可以直接求最大獨(dú)立集,因?yàn)椴荒艹橄竽芏謭D,所以如果想求獨(dú)立集,那么就只剩下一個(gè)比較暴力的np問(wèn)題了,就是最大團(tuán),雖說(shuō)是np問(wèn)題,但是可以靠一些很實(shí)用的剪紙和簡(jiǎn)單dp來(lái)優(yōu)化,這個(gè)題目還是輕松的過(guò)掉了,建圖的時(shí)候把不沖突的兩個(gè)點(diǎn)連接起來(lái),最后一遍最大團(tuán)就行了。同樣的還有POJ1185 炮兵陣地,只是建圖的時(shí)候的限制不一樣而已,別的都一樣,具體看代碼,明明是在學(xué)習(xí)dp,怎么又寫(xiě)圖論了。
#include<stdio.h>
#include<string.h>
#define N 1100
typedef struct
{
? ?int x ,y;
}NODE;
NODE node[N];
int map[N][N] ,n;
int dp[N] ,now[N];
int Ans;
void DFS(int s ,int sum)
{
? ?if(Ans < sum) ?Ans = sum;
? ?int tnow[N] ,able = 0;
? ?for(int i = s + 1 ;i <= n ;i ++)
? ?{
? ? ? tnow[i] = now[i];
? ? ? if(now[i]) able ++;
? ?}
? ?if(able + sum < Ans) return;
? ?for(int i = s + 1 ;i <= n ;i ++)
? ?{
? ? ? if(!tnow[i]) continue;
? ? ? if(sum + dp[i] <= Ans) return;
? ? ? for(int j = s+1 ;j <= n ;j ++)
? ? ? now[j] = tnow[j] & map[i][j];
? ? ? DFS(i ,sum + 1);
? ?}
}
int Max_Tuan()
{
? ?dp[n] = Ans = 1;
? ?for(int i = n - 1 ;i >= 1 ;i --)
? ?{
? ? ? for(int j = 1 ;j <= n ;j ++)
? ? ? now[j] = map[i][j];
? ? ? now[i] = 1;
? ? ? DFS(i ,1);
? ? ? dp[i] = Ans;
? ?}
? ?return Ans;
}
int abss(int x)
{
? ?return x > 0 ? x : -x;
}
int ok(int a ,int b)
{
? ?int dis = abss(node[a].x - node[b].x) + abss(node[a].y - node[b].y);
? ?if(dis == 2) return 0;
? ?return 1;
}
int main ()
{
? ?int nn ,mm ,i ,j ,a;
? ?while(~scanf("%d %d" ,&nn ,&mm))
? ?{
? ? ? int nowid = 0;
? ? ? for(i = 1 ;i <= nn ;i ++)
? ? ? for(j = 1 ;j <= mm ;j ++)
? ? ? {
? ? ? ? ?scanf("%d" ,&a);
? ? ? ? ?if(!a) continue;
? ? ? ? ?nowid ++;
? ? ? ? ?node[nowid].x = i ,node[nowid].y = j;
? ? ? }
? ? ? if(!nowid)
? ? ? {
? ? ? ? ?printf("0\n");
? ? ? ? ?continue;
? ? ? }
? ? ? memset(map ,0 ,sizeof(map));
? ? ? for(i = 1 ;i <= nowid ;i ++)
? ? ? for(j = i + 1 ;j <= nowid ;j ++)
? ? ? map[i][j] = map[j][i] = ok(i ,j);
? ? ? n = nowid;
? ? ? printf("%d\n" ,Max_Tuan());
? ?}
? ?return 0;
}
POJ 1185
炮兵陣地
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 19703 Accepted: 7610
Description
司令部的將軍們打算在N*M的網(wǎng)格地圖上部署他們的炮兵部隊(duì)。一個(gè)N*M的地圖由N行M列組成,地圖的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示),如下圖。在每一格平原地形上最多可以布置一支炮兵部隊(duì)(山地上不能夠部署炮兵部隊(duì));一支炮兵部隊(duì)在地圖上的攻擊范圍如圖中黑色區(qū)域所示:?
如果在地圖中的灰色所標(biāo)識(shí)的平原上部署一支炮兵部隊(duì),則圖中的黑色的網(wǎng)格表示它能夠攻擊到的區(qū)域:沿橫向左右各兩格,沿縱向上下各兩格。圖上其它白色網(wǎng)格均攻擊不到。從圖上可見(jiàn)炮兵的攻擊范圍不受地形的影響。?
現(xiàn)在,將軍們規(guī)劃如何部署炮兵部隊(duì),在防止誤傷的前提下(保證任何兩支炮兵部隊(duì)之間不能互相攻擊,即任何一支炮兵部隊(duì)都不在其他支炮兵部隊(duì)的攻擊范圍內(nèi)),在整個(gè)地圖區(qū)域內(nèi)最多能夠擺放多少我軍的炮兵部隊(duì)。?
Input
第一行包含兩個(gè)由空格分割開(kāi)的正整數(shù),分別表示N和M;?
接下來(lái)的N行,每一行含有連續(xù)的M個(gè)字符('P'或者'H'),中間沒(méi)有空格。按順序表示地圖中每一行的數(shù)據(jù)。N <= 100;M <= 10。
Output
僅一行,包含一個(gè)整數(shù)K,表示最多能擺放的炮兵部隊(duì)的數(shù)量。
Sample Input
5 4
PHPP
PPHH
PPPP
PHPP
PHHP
Sample Output
6
Source
? ??
#include<stdio.h>
#include<string.h>
#define N 1100
typedef struct
{
? ?int x ,y;
}NODE;
NODE node[N];
int map[N][N] ,n;
int dp[N] ,now[N];
int Ans;
void DFS(int s ,int sum)
{
? ?if(Ans < sum) ?Ans = sum;
? ?int tnow[N] ,able = 0;
? ?for(int i = s + 1 ;i <= n ;i ++)
? ?{
? ? ? tnow[i] = now[i];
? ? ? if(now[i]) able ++;
? ?}
? ?if(able + sum < Ans) return;
? ?for(int i = s + 1 ;i <= n ;i ++)
? ?{
? ? ? if(!tnow[i]) continue;
? ? ? if(sum + dp[i] <= Ans) return;
? ? ? for(int j = s+1 ;j <= n ;j ++)
? ? ? now[j] = tnow[j] & map[i][j];
? ? ? DFS(i ,sum + 1);
? ?}
}
int Max_Tuan()
{
? ?dp[n] = Ans = 1;
? ?for(int i = n - 1 ;i >= 1 ;i --)
? ?{
? ? ? for(int j = 1 ;j <= n ;j ++)
? ? ? now[j] = map[i][j];
? ? ? now[i] = 1;
? ? ? DFS(i ,1);
? ? ? dp[i] = Ans;
? ?}
? ?return Ans;
}
int abss(int x)
{
? ?return x > 0 ? x : -x;
}
int ok(int a ,int b)
{
? ? int xx = abss(node[a].x - node[b].x);
? ? int yy = abss(node[a].y - node[b].y);
? ? if(!xx && yy <= 2 || !yy && xx <= 2) return 0;
? ? return 1;
}
int main ()
{
? ?int nn ,mm ,i ,j ,a;
? ?char str[110];
? ?while(~scanf("%d %d" ,&nn ,&mm))
? ?{
? ? ? int nowid = 0;
? ? ? for(i = 1 ;i <= nn ;i ++) ?
? ? ? {
? ? ? ? ?scanf("%s" ,str);?
? ? ? ? ?for(j = 1 ;j <= mm ;j ++)
? ? ? ? ?{
? ? ? ? ? ?
? ? ? ? ? ? if(str[j-1] != 'P') continue;
? ? ? ? ? ? nowid ++;
? ? ? ? ? ? node[nowid].x = i ,node[nowid].y = j;
? ? ? ? ?}
? ? ? }
? ? ? if(!nowid)
? ? ? {
? ? ? ? ?printf("0\n");
? ? ? ? ?continue;
? ? ? }
? ? ? memset(map ,0 ,sizeof(map));
? ? ? for(i = 1 ;i <= nowid ;i ++)
? ? ? for(j = i + 1 ;j <= nowid ;j ++)
? ? ? map[i][j] = map[j][i] = ok(i ,j);
? ? ? n = nowid;
? ? ? printf("%d\n" ,Max_Tuan());
? ?}
? ?return 0;
}
? ??
? ??
??
? ? ??
? ? ??
? ? ? ? ?
? ?
? ? ??
? ? ??
總結(jié)
以上是生活随笔為你收集整理的hdu4539 郑厂长系列故事——排兵布阵 + POJ1158 炮兵阵地的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: POJ 3228 二分最大流
- 下一篇: poj 2472