提出 #66918353
ソースコード 拡げる
#include <bits/stdc++.h>
using namespace std;
// AtCoder Heuristic: Durability-Constrained Transport
// Beam Search Implementation with case-based heuristics
// Compile: g++ -std=c++17 -O2 main.cpp
constexpr int N = 20;
constexpr int MAX_BOX = N*N - 1; // 399
constexpr int BEAM_W = 64; // Beam width
constexpr int OP_LIMIT = 16000; // Max operations (move+pick+drop)
struct Box { int x, y, w, d; };
vector<Box> boxes;
int dist0[N][N]; // Manhattan from (0,0)
struct Held { int id, rem; };
struct State {
int px=0, py=0; // current position
int ops=0; // all ops count
int moves=0; // move count
array<uint64_t,7> mask{}; // remaining boxes
vector<Held> stack; // carried stack
string log; // operations log
int score=0; // heuristic score
};
inline bool has_box(const State &s, int id) {
return s.mask[id>>6] & (1ULL<<(id&63));
}
inline void remove_box(State &s, int id) {
s.mask[id>>6] &= ~(1ULL<<(id&63));
}
inline bool all_removed(const State &s) {
for(auto m: s.mask) if(m) return false;
return true;
}
// Step one move, update durability, count ops
bool step(State &st, char dir) {
if(st.ops >= OP_LIMIT) return false;
st.log.push_back(dir);
st.ops++; st.moves++;
if(dir=='U') st.px--;
else if(dir=='D') st.px++;
else if(dir=='L') st.py--;
else if(dir=='R') st.py++;
if(st.stack.empty()) return true;
int above = 0;
for(int i=(int)st.stack.size()-1; i>=0; --i) {
st.stack[i].rem -= above;
if(st.stack[i].rem <= 0) return false;
above += boxes[st.stack[i].id].w;
}
return true;
}
bool move_to(State &st, int nx, int ny) {
while(st.px < nx) if(!step(st,'D')) return false;
while(st.px > nx) if(!step(st,'U')) return false;
while(st.py < ny) if(!step(st,'R')) return false;
while(st.py > ny) if(!step(st,'L')) return false;
return true;
}
// Heuristic evaluation combining multiple criteria
int evaluate(const State &st) {
long long val = 0;
// 1. remaining boxes near origin
long long sumDist = 0;
for(int id=0; id<MAX_BOX; ++id) if(has_box(st,id)) {
auto &b = boxes[id]; sumDist += dist0[b.x][b.y];
}
val -= sumDist;
// 2. number carried
val += (long long)st.stack.size() * 500;
// 3. average durability ratio of carried: (d/w)
if(!st.stack.empty()) {
double avgRatio = 0;
for(auto &h: st.stack)
avgRatio += (double)h.rem / boxes[h.id].w;
avgRatio /= st.stack.size();
val += (int)(avgRatio * 100);
}
// 4. penalize moves
val -= st.moves * 5;
return (int)val;
}
// Beam expansion
vector<State> expand(const State &cur) {
vector<State> nxt;
// auto-drop at origin
if (!cur.stack.empty() && cur.px==0 && cur.py==0) {
State ns = cur;
if (ns.ops+1 <= OP_LIMIT) {
ns.ops++; // automatic drop, no log
ns.stack.clear();
ns.score = evaluate(ns);
nxt.push_back(move(ns));
}
return nxt;
}
// case: no box in hand -> pick farthest K in SE, else all
if (cur.stack.empty()) {
const int K = 4;
vector<pair<int,int>> cand;
for (int id=0; id<MAX_BOX; ++id) if (has_box(cur,id)) {
auto &b = boxes[id];
if (b.x>=cur.px && b.y>=cur.py) {
int d = abs(cur.px-b.x)+abs(cur.py-b.y);
cand.emplace_back(d,id);
}
}
if (cand.empty()) {
for (int id=0; id<MAX_BOX; ++id) if (has_box(cur,id)) {
auto &b = boxes[id];
int d = abs(cur.px-b.x)+abs(cur.py-b.y);
cand.emplace_back(d,id);
}
}
sort(cand.begin(),cand.end(),greater<>());
int take = min(K,(int)cand.size());
for (int i=0; i<take; ++i) {
int id = cand[i].second;
State ns = cur;
if (!move_to(ns, boxes[id].x, boxes[id].y)) continue;
if (ns.ops+1 > OP_LIMIT) continue;
// simulate stacking durability
int remSteps = dist0[boxes[id].x][boxes[id].y];
int above=0;
for (int j=(int)ns.stack.size()-1; j>=0; --j) above+=boxes[ns.stack[j].id].w;
bool ok=true;
for (auto &h: ns.stack) {
if (h.rem < above*remSteps) { ok=false; break; }
}
if (!ok) continue;
// perform pick
ns.stack.push_back({id, boxes[id].d});
remove_box(ns,id);
ns.log.push_back('1'); ns.ops++;
// ensure return to origin is possible
{
State tmp = ns;
if (!move_to(tmp,0,0)) continue;
}
ns.score = evaluate(ns);
nxt.push_back(move(ns));
}
} else {
// case: carrying -> pick NW candidates or return
const int K2 = 2;
vector<pair<double,int>> cand;
for (int id=0; id<MAX_BOX; ++id) if (has_box(cur,id)) {
auto &b = boxes[id];
if (b.x < cur.px && b.y < cur.py) {
double ratio = double(b.d)/b.w;
int d = abs(cur.px-b.x)+abs(cur.py-b.y);
cand.emplace_back(ratio-d*0.1, id);
}
}
if (cand.empty()) {
for (int id=0; id<MAX_BOX; ++id) if (has_box(cur,id)) {
auto &b = boxes[id];
double ratio = double(b.d)/b.w;
int d = abs(cur.px-b.x)+abs(cur.py-b.y);
cand.emplace_back(ratio-d*0.1, id);
}
}
sort(cand.begin(), cand.end(), greater<>());
int take2 = min(K2, (int)cand.size());
for (int i=0; i<take2; ++i) {
int id = cand[i].second;
State ns = cur;
if (!move_to(ns, boxes[id].x, boxes[id].y)) continue;
if (ns.ops+1 > OP_LIMIT) continue;
// staging: simulate return emptiness
bool reach=false;
int tx=ns.px, ty=ns.py;
while (tx>0 || ty>0) {
if (tx>0) tx--; else if (ty>0) ty--;
int bid=-1;
for (int z=0; z<MAX_BOX; ++z) if (boxes[z].x==tx && boxes[z].y==ty && has_box(ns,z)) { bid=z; break; }
if (bid<0) { reach=true; break; }
}
if (!reach) continue;
// durability check
int remSteps = dist0[boxes[id].x][boxes[id].y];
int above=0;
for (int j=(int)ns.stack.size()-1;j>=0;--j) above+=boxes[ns.stack[j].id].w;
bool ok=true;
for (auto &h: ns.stack) if (h.rem < above*remSteps) { ok=false; break; }
if (!ok) continue;
ns.stack.push_back({id, boxes[id].d});
remove_box(ns,id);
ns.log.push_back('1'); ns.ops++;
// ensure return
{
State tmp=ns;
if (!move_to(tmp,0,0)) continue;
}
ns.score = evaluate(ns);
nxt.push_back(move(ns));
}
// return & auto-drop
{
State ns=cur;
if(move_to(ns,0,0) && !ns.stack.empty() && ns.ops+1<=OP_LIMIT) {
ns.ops++;
ns.stack.clear();
ns.score = evaluate(ns);
nxt.push_back(move(ns));
}
}
}
return nxt;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n; cin>>n;
vector<vector<int>> wg(n,vector<int>(n)), dg(n,vector<int>(n));
for(int i=0;i<n;i++) for(int j=0;j<n;j++) cin>>wg[i][j];
for(int i=0;i<n;i++) for(int j=0;j<n;j++) cin>>dg[i][j];
boxes.reserve(MAX_BOX);
for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(i||j)
boxes.push_back({i,j,wg[i][j],dg[i][j]});
for(int i=0;i<n;i++) for(int j=0;j<n;j++) dist0[i][j] = i+j;
State init;
init.mask.fill(0);
for(int id=0;id<MAX_BOX;++id) init.mask[id>>6] |= 1ULL<<(id&63);
init.score = evaluate(init);
vector<State> beam{init}, buf;
beam.reserve(BEAM_W);
buf.reserve(BEAM_W*4);
while(!beam.empty()){
buf.clear();
for(auto &s: beam){
auto v = expand(s);
for(auto &ns: v) buf.push_back(move(ns));
}
if(buf.empty()) break;
nth_element(buf.begin(), buf.begin()+min((int)buf.size(),BEAM_W), buf.end(),
[](auto &a, auto &b){ return a.score > b.score; });
beam.assign(buf.begin(), buf.begin()+min((int)buf.size(),BEAM_W));
if(all_removed(beam[0]) && beam[0].stack.empty()) break;
}
for(char c: beam[0].log) cout<<c<<"\n";
return 0;
}
提出情報
| 提出日時 | |
|---|---|
| 問題 | A - Durability-Constrained Transport |
| ユーザ | koshinM |
| 言語 | C++ 17 (gcc 12.2) |
| 得点 | 675574 |
| コード長 | 9034 Byte |
| 結果 | AC |
| 実行時間 | 367 ms |
| メモリ | 11700 KiB |
ジャッジ結果
| セット名 | test_ALL | ||
|---|---|---|---|
| 得点 / 配点 | 675574 / 2460000 | ||
| 結果 |
|
| セット名 | テストケース |
|---|---|
| test_ALL | test_0000.txt, test_0001.txt, test_0002.txt, test_0003.txt, test_0004.txt, test_0005.txt, test_0006.txt, test_0007.txt, test_0008.txt, test_0009.txt, test_0010.txt, test_0011.txt, test_0012.txt, test_0013.txt, test_0014.txt, test_0015.txt, test_0016.txt, test_0017.txt, test_0018.txt, test_0019.txt, test_0020.txt, test_0021.txt, test_0022.txt, test_0023.txt, test_0024.txt, test_0025.txt, test_0026.txt, test_0027.txt, test_0028.txt, test_0029.txt, test_0030.txt, test_0031.txt, test_0032.txt, test_0033.txt, test_0034.txt, test_0035.txt, test_0036.txt, test_0037.txt, test_0038.txt, test_0039.txt, test_0040.txt, test_0041.txt, test_0042.txt, test_0043.txt, test_0044.txt, test_0045.txt, test_0046.txt, test_0047.txt, test_0048.txt, test_0049.txt, test_0050.txt, test_0051.txt, test_0052.txt, test_0053.txt, test_0054.txt, test_0055.txt, test_0056.txt, test_0057.txt, test_0058.txt, test_0059.txt, test_0060.txt, test_0061.txt, test_0062.txt, test_0063.txt, test_0064.txt, test_0065.txt, test_0066.txt, test_0067.txt, test_0068.txt, test_0069.txt, test_0070.txt, test_0071.txt, test_0072.txt, test_0073.txt, test_0074.txt, test_0075.txt, test_0076.txt, test_0077.txt, test_0078.txt, test_0079.txt, test_0080.txt, test_0081.txt, test_0082.txt, test_0083.txt, test_0084.txt, test_0085.txt, test_0086.txt, test_0087.txt, test_0088.txt, test_0089.txt, test_0090.txt, test_0091.txt, test_0092.txt, test_0093.txt, test_0094.txt, test_0095.txt, test_0096.txt, test_0097.txt, test_0098.txt, test_0099.txt, test_0100.txt, test_0101.txt, test_0102.txt, test_0103.txt, test_0104.txt, test_0105.txt, test_0106.txt, test_0107.txt, test_0108.txt, test_0109.txt, test_0110.txt, test_0111.txt, test_0112.txt, test_0113.txt, test_0114.txt, test_0115.txt, test_0116.txt, test_0117.txt, test_0118.txt, test_0119.txt, test_0120.txt, test_0121.txt, test_0122.txt, test_0123.txt, test_0124.txt, test_0125.txt, test_0126.txt, test_0127.txt, test_0128.txt, test_0129.txt, test_0130.txt, test_0131.txt, test_0132.txt, test_0133.txt, test_0134.txt, test_0135.txt, test_0136.txt, test_0137.txt, test_0138.txt, test_0139.txt, test_0140.txt, test_0141.txt, test_0142.txt, test_0143.txt, test_0144.txt, test_0145.txt, test_0146.txt, test_0147.txt, test_0148.txt, test_0149.txt |
| ケース名 | 結果 | 実行時間 | メモリ |
|---|---|---|---|
| test_0000.txt | AC | 325 ms | 10956 KiB |
| test_0001.txt | AC | 335 ms | 11552 KiB |
| test_0002.txt | AC | 337 ms | 11308 KiB |
| test_0003.txt | AC | 321 ms | 11100 KiB |
| test_0004.txt | AC | 293 ms | 10332 KiB |
| test_0005.txt | AC | 347 ms | 11420 KiB |
| test_0006.txt | AC | 340 ms | 11236 KiB |
| test_0007.txt | AC | 298 ms | 10852 KiB |
| test_0008.txt | AC | 303 ms | 10852 KiB |
| test_0009.txt | AC | 322 ms | 11580 KiB |
| test_0010.txt | AC | 358 ms | 11516 KiB |
| test_0011.txt | AC | 315 ms | 11180 KiB |
| test_0012.txt | AC | 306 ms | 10776 KiB |
| test_0013.txt | AC | 306 ms | 11320 KiB |
| test_0014.txt | AC | 310 ms | 11176 KiB |
| test_0015.txt | AC | 315 ms | 11392 KiB |
| test_0016.txt | AC | 317 ms | 11264 KiB |
| test_0017.txt | AC | 323 ms | 11508 KiB |
| test_0018.txt | AC | 311 ms | 11332 KiB |
| test_0019.txt | AC | 328 ms | 10812 KiB |
| test_0020.txt | AC | 308 ms | 10688 KiB |
| test_0021.txt | AC | 324 ms | 10084 KiB |
| test_0022.txt | AC | 299 ms | 10568 KiB |
| test_0023.txt | AC | 318 ms | 10904 KiB |
| test_0024.txt | AC | 325 ms | 11168 KiB |
| test_0025.txt | AC | 321 ms | 11220 KiB |
| test_0026.txt | AC | 340 ms | 11408 KiB |
| test_0027.txt | AC | 325 ms | 10856 KiB |
| test_0028.txt | AC | 310 ms | 11124 KiB |
| test_0029.txt | AC | 327 ms | 11260 KiB |
| test_0030.txt | AC | 314 ms | 11312 KiB |
| test_0031.txt | AC | 320 ms | 11316 KiB |
| test_0032.txt | AC | 325 ms | 11396 KiB |
| test_0033.txt | AC | 326 ms | 11540 KiB |
| test_0034.txt | AC | 305 ms | 11120 KiB |
| test_0035.txt | AC | 319 ms | 10564 KiB |
| test_0036.txt | AC | 342 ms | 11232 KiB |
| test_0037.txt | AC | 315 ms | 10864 KiB |
| test_0038.txt | AC | 348 ms | 11620 KiB |
| test_0039.txt | AC | 302 ms | 11312 KiB |
| test_0040.txt | AC | 309 ms | 11072 KiB |
| test_0041.txt | AC | 319 ms | 11412 KiB |
| test_0042.txt | AC | 344 ms | 11204 KiB |
| test_0043.txt | AC | 310 ms | 11384 KiB |
| test_0044.txt | AC | 311 ms | 10712 KiB |
| test_0045.txt | AC | 314 ms | 11292 KiB |
| test_0046.txt | AC | 326 ms | 11396 KiB |
| test_0047.txt | AC | 310 ms | 10624 KiB |
| test_0048.txt | AC | 305 ms | 10724 KiB |
| test_0049.txt | AC | 301 ms | 10852 KiB |
| test_0050.txt | AC | 292 ms | 10392 KiB |
| test_0051.txt | AC | 307 ms | 11220 KiB |
| test_0052.txt | AC | 330 ms | 11036 KiB |
| test_0053.txt | AC | 325 ms | 10736 KiB |
| test_0054.txt | AC | 304 ms | 10748 KiB |
| test_0055.txt | AC | 346 ms | 10652 KiB |
| test_0056.txt | AC | 299 ms | 10736 KiB |
| test_0057.txt | AC | 309 ms | 10896 KiB |
| test_0058.txt | AC | 313 ms | 10440 KiB |
| test_0059.txt | AC | 353 ms | 11480 KiB |
| test_0060.txt | AC | 316 ms | 11304 KiB |
| test_0061.txt | AC | 325 ms | 11288 KiB |
| test_0062.txt | AC | 323 ms | 11300 KiB |
| test_0063.txt | AC | 326 ms | 11360 KiB |
| test_0064.txt | AC | 306 ms | 11036 KiB |
| test_0065.txt | AC | 317 ms | 11308 KiB |
| test_0066.txt | AC | 316 ms | 11272 KiB |
| test_0067.txt | AC | 301 ms | 10620 KiB |
| test_0068.txt | AC | 319 ms | 11356 KiB |
| test_0069.txt | AC | 307 ms | 11108 KiB |
| test_0070.txt | AC | 304 ms | 10524 KiB |
| test_0071.txt | AC | 316 ms | 11340 KiB |
| test_0072.txt | AC | 337 ms | 11280 KiB |
| test_0073.txt | AC | 326 ms | 11288 KiB |
| test_0074.txt | AC | 294 ms | 10236 KiB |
| test_0075.txt | AC | 352 ms | 11580 KiB |
| test_0076.txt | AC | 340 ms | 10744 KiB |
| test_0077.txt | AC | 299 ms | 10272 KiB |
| test_0078.txt | AC | 313 ms | 11088 KiB |
| test_0079.txt | AC | 317 ms | 11244 KiB |
| test_0080.txt | AC | 326 ms | 11412 KiB |
| test_0081.txt | AC | 330 ms | 11448 KiB |
| test_0082.txt | AC | 308 ms | 10448 KiB |
| test_0083.txt | AC | 334 ms | 11220 KiB |
| test_0084.txt | AC | 309 ms | 10896 KiB |
| test_0085.txt | AC | 313 ms | 10860 KiB |
| test_0086.txt | AC | 300 ms | 10692 KiB |
| test_0087.txt | AC | 305 ms | 10316 KiB |
| test_0088.txt | AC | 326 ms | 11428 KiB |
| test_0089.txt | AC | 316 ms | 11216 KiB |
| test_0090.txt | AC | 313 ms | 11100 KiB |
| test_0091.txt | AC | 313 ms | 11192 KiB |
| test_0092.txt | AC | 311 ms | 11300 KiB |
| test_0093.txt | AC | 295 ms | 10424 KiB |
| test_0094.txt | AC | 350 ms | 11356 KiB |
| test_0095.txt | AC | 310 ms | 10484 KiB |
| test_0096.txt | AC | 331 ms | 11464 KiB |
| test_0097.txt | AC | 307 ms | 11160 KiB |
| test_0098.txt | AC | 316 ms | 11332 KiB |
| test_0099.txt | AC | 315 ms | 11320 KiB |
| test_0100.txt | AC | 326 ms | 10612 KiB |
| test_0101.txt | AC | 339 ms | 10924 KiB |
| test_0102.txt | AC | 321 ms | 11156 KiB |
| test_0103.txt | AC | 327 ms | 11352 KiB |
| test_0104.txt | AC | 335 ms | 10636 KiB |
| test_0105.txt | AC | 309 ms | 10712 KiB |
| test_0106.txt | AC | 313 ms | 11048 KiB |
| test_0107.txt | AC | 314 ms | 11156 KiB |
| test_0108.txt | AC | 321 ms | 11304 KiB |
| test_0109.txt | AC | 313 ms | 11136 KiB |
| test_0110.txt | AC | 309 ms | 11116 KiB |
| test_0111.txt | AC | 343 ms | 11412 KiB |
| test_0112.txt | AC | 307 ms | 11204 KiB |
| test_0113.txt | AC | 316 ms | 11340 KiB |
| test_0114.txt | AC | 305 ms | 11100 KiB |
| test_0115.txt | AC | 324 ms | 11296 KiB |
| test_0116.txt | AC | 305 ms | 10908 KiB |
| test_0117.txt | AC | 304 ms | 10756 KiB |
| test_0118.txt | AC | 326 ms | 10900 KiB |
| test_0119.txt | AC | 310 ms | 11108 KiB |
| test_0120.txt | AC | 329 ms | 11384 KiB |
| test_0121.txt | AC | 302 ms | 11100 KiB |
| test_0122.txt | AC | 339 ms | 11516 KiB |
| test_0123.txt | AC | 367 ms | 11628 KiB |
| test_0124.txt | AC | 306 ms | 11068 KiB |
| test_0125.txt | AC | 303 ms | 10644 KiB |
| test_0126.txt | AC | 311 ms | 11432 KiB |
| test_0127.txt | AC | 324 ms | 11412 KiB |
| test_0128.txt | AC | 334 ms | 11164 KiB |
| test_0129.txt | AC | 325 ms | 11292 KiB |
| test_0130.txt | AC | 319 ms | 11408 KiB |
| test_0131.txt | AC | 320 ms | 11700 KiB |
| test_0132.txt | AC | 314 ms | 11344 KiB |
| test_0133.txt | AC | 320 ms | 11448 KiB |
| test_0134.txt | AC | 318 ms | 11316 KiB |
| test_0135.txt | AC | 357 ms | 11484 KiB |
| test_0136.txt | AC | 320 ms | 11148 KiB |
| test_0137.txt | AC | 340 ms | 11164 KiB |
| test_0138.txt | AC | 316 ms | 10856 KiB |
| test_0139.txt | AC | 325 ms | 11312 KiB |
| test_0140.txt | AC | 330 ms | 11288 KiB |
| test_0141.txt | AC | 310 ms | 10820 KiB |
| test_0142.txt | AC | 302 ms | 10828 KiB |
| test_0143.txt | AC | 308 ms | 10620 KiB |
| test_0144.txt | AC | 320 ms | 11408 KiB |
| test_0145.txt | AC | 323 ms | 11188 KiB |
| test_0146.txt | AC | 337 ms | 10972 KiB |
| test_0147.txt | AC | 335 ms | 11612 KiB |
| test_0148.txt | AC | 311 ms | 11256 KiB |
| test_0149.txt | AC | 320 ms | 11360 KiB |