[Offer收割]程式設計練習賽1 hihocoder 1271 艦隊遊戲 (狀態壓縮+貪心 好題)
描述
小Hi最近在玩一款組建艦隊出海進行戰爭的遊戲,在這個遊戲中,小Hi需要根據需要組建一隻艦隊,一支艦隊裡最多同時存在N艘艦船,每艘艦船最多同時裝備M個裝備。
在一次關卡中,小Hi希望能夠組建一隻僅由航母構成的艦隊,這意味著所有艦船的裝備都是某種型別的飛機,小Hi將要使用的飛機有兩種型別:對空飛機和對艦飛機,顧名思義,對空飛機用於和敵對艦船搭載的飛機進行對抗,而對艦飛機則直接用於攻擊敵對艦船本身。
每艘航母的M個裝備欄位是不一樣的,我們可以用“搭載量”來對其進行量化描述,有些裝備欄位的搭載量較高,有些裝備欄位的搭載量較低,對於第i艘艦船,我們用Ai,j表示其第j個裝備欄位的搭載量。
小Hi的軍備庫裡有T架飛機,我們Bi表示第i架飛機的對空攻擊力,並用Ci表示第i架飛機的對艦攻擊力,其中對空飛機的對艦攻擊力為0,對艦飛機的對空攻擊力為0。
為艦船裝備飛機,會提高艦隊的“制空值”和“傷害值”。艦隊的制空值為所有飛機的對空攻擊力與其對應的裝備欄位的搭載量的乘積之和,即:
制空值=
其中pi,j表示放置在第i艘艦船的第j個裝備欄位的飛機編號。同理,艦隊的傷害值為所有飛機的對艦攻擊力與其對應的裝備欄位的搭載量的乘積之和,即:
傷害值=
為了能夠順利的通過關卡,小Hi需要使得艦隊的制空值不低於一個給定的值S,並且希望在這個條件下艦隊的傷害值越高越好,這樣能夠儘量減少艦隊的損耗。
同時,由於一艘艦船至少要裝備一架對艦飛機才能夠在炮擊戰中發動攻擊,所以小Hi也好奇是否存在在滿足制空值限制且傷害值最高的情況下,同時滿足每一艘艦船至少裝備一架對艦飛機。
而這個問題,就有待你來進行計算了~
輸入
輸入第一行為一個正整數Q,表示測試資料的組數。
在每組測試資料的第一行,為4個正整數N、M、T和S,意義如之前所述。
第2行~第n+1行,每行m個正整數,對應矩陣A
第n+2行,為T個正整數B1 .. BT
第n+3行,為T個正整數C1 .. CT
對於30%的資料,滿足N<=2,M<=2,T<=20,Q<=100
對於剩下70%的資料,滿足N<=4,M<=4,T<=1000,Q<=3
對於100%的資料,滿足1<=Ai,j, Bi, Ci <= 1000,0<= S <= 108
輸出
對於每組測試資料,如果存在滿足制空值限制的方案的話,則首先在第一行輸出在滿足制空值限制下能夠達到的最大攻擊力D,在第二行中,如果在滿足制空值限制且傷害值最高的情況下,能夠同時滿足每一艘艦船至少裝備一架對艦飛機,則輸出Yes,否則輸出No。
如果不存在滿足制空值限制的方案的話,則輸出一行Not Exist。
3 1 2 1 38 4 5 0 5 1 2 8 7 1 4 0 3 2 0 0 2 0 0 5 0 0 3 3 0 3 4 2 1 4 29 5 3 0 4 3 0 1 0 0 3樣例輸出
Not Exist 5 Yes 0 No
題目連結:http://hihocoder.com/problemset/problem/1271
題目分析:這題現場ac的程式碼再交上去有一部分就wa了,不wa的有些也可以很輕鬆被hack。。。因為n和m很小,所以可以把狀態壓縮,用1表示放對空飛機,0表示放對艦飛機,對值直接從小到大排序,然後就是列舉狀態貪心計算,要注意兩點,算C的時候要把對應的狀態記錄下來,因為能放的位置排序完了後不一定都夠放,有個剪枝,如果當前位置數大於飛機數了直接不用算了,因為當位置數小於等於飛機數的時候的狀態都算過了,這是那種情況的子集,判斷是否每個艦都有對艦飛機時,一定要與算C時的狀態對應
另提供幾組hack資料
2
4 4 4 20
5 5 5 5
1 1 1 1
1 1 1 1
1 1 1 1
0 2 2 0
5 0 0 1
4 3 3 5
6 8 3
4 8 6
6 6 1
1 1 5
1 0 0
0 10 10
答案:
30
No
160
No
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
int const MAX = 1e3 + 5;
int n, m, t, s;
int sz_a, sz_b, sz_c;
int b[MAX], B[MAX], c[MAX], C[MAX];
struct A
{
int num, sta;
}a[5][5], tmp[20];
bool cmp(A x, A y)
{
return x.num > y.num;
}
int cal_B(int sta)
{
memset(tmp, 0, sizeof(tmp));
sz_a = 0;
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
if(sta & (1 << (i * m + j)))
tmp[sz_a ++].num = a[i][j].num;
sort(tmp, tmp + sz_a, cmp);
int res = 0;
for(int i = 0, j = 0; i < sz_a && j < sz_b; i++, j++)
res += tmp[i].num * B[j];
return res;
}
int cal_C(int sta)
{
memset(tmp, 0, sizeof(tmp));
sz_a = 0;
for(int i = 0; i < n && sz_a <= sz_c; i++)
for(int j = 0; j < m && sz_a <= sz_c; j++)
if(!(sta & (1 << (i * m + j))))
{
tmp[sz_a].num = a[i][j].num;
tmp[sz_a ++].sta = a[i][j].sta;
}
sort(tmp, tmp + sz_a, cmp);
int res = 0;
for(int i = 0, j = 0; i < sz_a && j < sz_c; i++, j++)
res += tmp[i].num * C[j];
return res;
}
bool Judge_C(int sta)
{
for(int i = 0; i < n; i++)
{
bool flag = false;
for(int j = 0; j < m && !flag; j++)
for(int k = 0; k < min(sz_a, sz_c) && !flag; k++)
if(((1 << (i * m + j)) & tmp[k].sta))
flag = true;
if(!flag)
return false;
}
return true;
}
int main()
{
int T;
scanf("%d", &T);
while(T --)
{
sz_b = 0;
sz_c = 0;
scanf("%d %d %d %d", &n, &m, &t, &s);
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
scanf("%d", &a[i][j].num);
a[i][j].sta = (1 << (i * m + j));
}
}
for(int i = 0; i < t; i++)
{
scanf("%d", &b[i]);
if(b[i])
B[sz_b ++] = b[i];
}
for(int i = 0; i < t; i++)
{
scanf("%d", &c[i]);
if(c[i])
C[sz_c ++] = c[i];
}
sort(B, B + sz_b, greater<int>());
sort(C, C + sz_c, greater<int>());
int ans = -1, tot = 1 << (n * m);
bool hasC = false;
for(int sta = 0; sta < tot; sta++)
{
if(cal_B(sta) >= s)
{
int maC = cal_C(sta);
if(maC > ans || (maC == ans && !hasC))
{
ans = maC;
hasC = Judge_C(sta);
}
}
}
if(ans == -1)
printf("Not Exist\n");
else
printf("%d\n%s\n", ans, hasC ? "Yes" : "No");
}
}
相關文章
- [Offer收割]程式設計練習賽2 hihocoder 1273 (DFS + 狀壓)程式設計
- [Offer收割]程式設計練習賽1 hihocoder 1268 九宮 (DFS)程式設計
- [Offer收割]程式設計練習賽1 hihocoder 1270 建造基地 (完全揹包)程式設計
- [Offer收割]程式設計練習賽2 hihocoder 1272 買零食 (DFS 或 dp 水題)程式設計
- [Offer收割]程式設計練習賽2 hihocoder 1275 掃地機器人 (計算幾何+模擬 比較煩)程式設計機器人
- [Offer收割]程式設計練習賽1 hihocoder 1269 優化延遲 (二分+優先權佇列)程式設計優化佇列
- 程式設計假期練習題--1程式設計
- 牛客練習賽40 B 小A與任務(貪心)
- 演算法學習之路|狀態壓縮dp演算法
- 好程式設計師web前端分享前端 javascript 練習題程式設計師Web前端JavaScript
- 好程式設計師web前端教程分享javascript 練習題程式設計師Web前端JavaScript
- 貪心演算法——Huffman 壓縮編碼的實現演算法
- 團體程式設計天梯賽-練習集程式設計
- 【好書推薦】《劍指Offer》之硬技能(程式設計題1~6)程式設計
- 好程式設計師雲端計算學習路線分享檔案打包及壓縮程式設計師
- 好程式設計師web前端教程分javascript練習題-事件程式設計師Web前端JavaScript事件
- 好程式設計師web前端分享前端javascript練習題三程式設計師Web前端JavaScript
- 好程式設計師web前端分享前端javascript練習題一程式設計師Web前端JavaScript
- 論文閱讀 狀態壓縮
- 團體程式設計天梯賽-練習集 L1-038 新世界程式設計
- 程式設計假期練習題--2程式設計
- 程式設計假期練習題--3程式設計
- 幽默:進入心流狀態的程式設計師跨年程式設計師
- 好程式設計師web前端教程分享前端javascript練習題二程式設計師Web前端JavaScript
- 好程式設計師web前端教程分享前端javascript練習題三程式設計師Web前端JavaScript
- 好程式設計師web前端教程分享前端 javascript 練習題二程式設計師Web前端JavaScript
- 2017廣東工業大學程式設計競賽決賽 題解&原始碼(A,數學解方程,B,貪心博弈,C,遞迴,D,水,E,貪心,面試題,F,貪心,列舉,LCA,G,dp,記憶化搜尋,H,思維題)...程式設計原始碼遞迴面試題
- POJ3279 Fliptile【狀態壓縮+DFS】
- 狀態壓縮動態規劃 -- 炮兵陣地動態規劃
- 舉例闡述利用“心流狀態”設計遊戲的要點遊戲
- 好程式設計師web前端教程分享前端javascript練習題之promise程式設計師Web前端JavaScriptPromise
- C++奧賽一本通貪心題解C++
- HDU 5135 Little Zu Chongzhi's Triangles(狀壓dp或者貪心)
- 程式設計實踐(Pandas)綜合練習1程式設計
- 程式設計練習程式設計
- HDU 5339 Untitled (狀態壓縮列舉)
- 好程式設計師web前端教程分享前端javascript練習題Ajax封裝程式設計師Web前端JavaScript封裝
- ACM-ICPC 2018 南京賽區網路預賽__E AC Challenge【狀態壓縮+DP】ACM