日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

hdu4784 不错的搜索( 买卖盐,要求整钱最多)

發布時間:2025/6/17 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hdu4784 不错的搜索( 买卖盐,要求整钱最多) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意:
? ? ? 給你一個有向圖,每個節點上都有一個鹽價,然后給你k個空間,么個空間上節點與節點的距離不變,但鹽價不同,對于每一個節點,有三種操作,賣一袋鹽,買一袋鹽 ,不交易,每一個節點可以跳掉(當前空間+1)%K的空間(特別注意,起點1和終點n不可以穿越),花費是時間1,金錢0 ,節點與節點之間都有花費時間和花費金錢,過程中金錢不可以是負數,問從節點1出發,在限制的時間內到達節點n的最大金錢數。


思路:

? ? ?這個題目做了將近兩天,一開始寫了各種深搜,各種超時,各種wa然后就開始各種廣搜,寫了很多版本,終于有一個能過的了,這個題目關鍵是就超時問題,說下思路,首先我們可以開一個數組mark[i][t][k][b] 表示的是第i個節點第t時刻,在第k層,有b袋鹽的最大金錢數,然后就是搜索,寫完了就是各種超時?為什么會超時,是因為我們進隊出隊次數太多,如果隨意一算可能會這么想 可能會如認為進隊次數是 N * T * K * B也就是mark的最大組合數,其實不然,對于同一個狀態可能會進隊多次,如果我們什么也不管,直接暴力,就是能更新就更新然后進隊列,那么就會出現這么一種情況“當前這一步比之前的大了,我們直接更新進隊,過了一會之后又來了一個,更新后的更大了,那么我們在更新進入隊列”不要小看這兩次進隊,其實第一次進隊我們所付出的代價是什么,代價是進隊后更新后面的可更新的,等第二次進隊了,再把后面的能更新的又更新了,這樣的話,暴搜的代價就很大了,具體多大我算不明白,但妥妥保證你超時,就算你之前寫一個逆向的最短路作為優化,照樣超時(我試過很多種),那么該怎么辦呢?其實對于每一個點,我們可以先把他的最優求出來,然后再去更新別人,因為是最優,所以這個點只會進隊列一次,那怎么求最優呢?我們可以開個優先隊列,就是把廣搜的隊列用優先隊列,每次取出時間最小的,這樣對于當前時間,比如是4,那么5這個時間點更新的時候<=4的肯定更新到最優了,所以這樣每個點只要進隊列一次就行了,優化了時間就可以ac了,如果你不滿足于ac,還想更快,可以在寫一個最短路去優化,反向存邊,時間是權值,從終點跑一遍最短路,然后對于每一步來說,如果時間已經不能到終點了,那么當前終點就直接continue了。


#include<stdio.h> #include<string.h> #include<queue>#define N_node 110 #define N_edge 220 #define INF 1000000000 using namespace std;typedef struct {int to ,next ,time ,money; }STAR;typedef struct NODE {int nowt ,nowc ,nowy ,id;friend bool operator < (NODE a ,NODE b){return a.nowt < b.nowt;} }NODE;STAR E[N_edge]; NODE xin ,tou; int list[N_node] ,tot; int pic[6][N_node]; int mark[N_node][220][8][8]; int mk[N_node][220][8][8]; int N ,M ,B ,K ,R ,T ,Ans;void add(int a ,int b ,int c ,int d) {E[++tot].to = b;E[tot].time = c;E[tot].money = d;E[tot].next = list[a];list[a] = tot; }void BFS() {memset(mark ,255 ,sizeof(mark));memset(mk ,0 ,sizeof(mk));xin.id = 1 ,xin.nowc = 0 ,xin.nowt = T ,xin.nowy = 0;priority_queue<NODE>q;q.push(xin);mark[xin.id][xin.nowt][xin.nowc][xin.nowy] = R;mk[xin.id][xin.nowt][xin.nowc][xin.nowy] = 1;while(!q.empty()){tou = q.top();q.pop(); if(tou.id == N){if(Ans < mark[tou.id][tou.nowt][tou.nowc][tou.nowy])Ans = mark[tou.id][tou.nowt][tou.nowc][tou.nowy];continue;}for(int k = list[tou.id] ; k ;k = E[k].next){xin.id = E[k].to;xin.nowc = tou.nowc;xin.nowt = tou.nowt - E[k].time;int cost = mark[tou.id][tou.nowt][tou.nowc][tou.nowy] - E[k].money;if(xin.nowt < 0 || cost < 0) continue;if(xin.id == 1 && xin.nowc || xin.id == N && xin.nowc)continue;//不交易 xin.nowy = tou.nowy;if(cost > mark[xin.id][xin.nowt][xin.nowc][xin.nowy]){mark[xin.id][xin.nowt][xin.nowc][xin.nowy] = cost;if(!mk[xin.id][xin.nowt][xin.nowc][xin.nowy]) {mk[xin.id][xin.nowt][xin.nowc][xin.nowy] = 1;q.push(xin);}}if(xin.id == 1 || xin.id == N) continue;//買 xin.nowy = tou.nowy + 1;if(xin.nowy <= B && cost - pic[xin.nowc][xin.id] >= 0){if(cost - pic[xin.nowc][xin.id] > mark[xin.id][xin.nowt][xin.nowc][xin.nowy]){mark[xin.id][xin.nowt][xin.nowc][xin.nowy] = cost - pic[xin.nowc][xin.id];if(!mk[xin.id][xin.nowt][xin.nowc][xin.nowy]){mk[xin.id][xin.nowt][xin.nowc][xin.nowy] = 1;q.push(xin);}}} //賣 xin.nowy = tou.nowy - 1;if(xin.nowy >= 0){if(cost + pic[xin.nowc][xin.id] > mark[xin.id][xin.nowt][xin.nowc][xin.nowy]){mark[xin.id][xin.nowt][xin.nowc][xin.nowy] = cost + pic[xin.nowc][xin.id];if(!mk[xin.id][xin.nowt][xin.nowc][xin.nowy]){mk[xin.id][xin.nowt][xin.nowc][xin.nowy] = 1;q.push(xin);}}} }if(tou.id == 1 || tou.id == N) continue;xin.id = tou.id;xin.nowc = (tou.nowc + 1) % K;xin.nowt = tou.nowt - 1;if(xin.nowt < 0) continue;int cost = mark[tou.id][tou.nowt][tou.nowc][tou.nowy];//不交易 xin.nowy = tou.nowy;if(cost > mark[xin.id][xin.nowt][xin.nowc][xin.nowy]){mark[xin.id][xin.nowt][xin.nowc][xin.nowy] = cost;if(!mk[xin.id][xin.nowt][xin.nowc][xin.nowy]) {mk[xin.id][xin.nowt][xin.nowc][xin.nowy] = 1;q.push(xin);}}//買 xin.nowy = tou.nowy + 1;if(xin.nowy <= B && cost - pic[xin.nowc][xin.id] >= 0){if(cost - pic[xin.nowc][xin.id] > mark[xin.id][xin.nowt][xin.nowc][xin.nowy]){mark[xin.id][xin.nowt][xin.nowc][xin.nowy] = cost - pic[xin.nowc][xin.id];if(!mk[xin.id][xin.nowt][xin.nowc][xin.nowy]){mk[xin.id][xin.nowt][xin.nowc][xin.nowy] = 1;q.push(xin);}}} //賣 xin.nowy = tou.nowy - 1;if(xin.nowy >= 0){if(cost + pic[xin.nowc][xin.id] > mark[xin.id][xin.nowt][xin.nowc][xin.nowy]){mark[xin.id][xin.nowt][xin.nowc][xin.nowy] = cost + pic[xin.nowc][xin.id];if(!mk[xin.id][xin.nowt][xin.nowc][xin.nowy]){mk[xin.id][xin.nowt][xin.nowc][xin.nowy] = 1;q.push(xin);}}} } }int main () {int i ,j ,a ,b ,c ,d;int cas = 1 ,t;scanf("%d" ,&t);while(t--){scanf("%d %d %d %d %d %d" ,&N ,&M ,&B ,&K ,&R ,&T);for(i = 0 ;i < K ;i ++)for(j = 1 ;j <= N ;j ++)scanf("%d" ,&pic[i][j]);memset(list ,0 ,sizeof(list)) ,tot = 1;for(i = 1 ;i <= M ;i ++){scanf("%d %d %d %d" ,&a ,&b ,&c ,&d);add(a ,b ,c ,d);}Ans = -1;BFS();printf("Case #%d: " ,cas ++);Ans == -1 ? puts("Forever Alone"):printf("%d\n" ,Ans);}return 0; }

總結

以上是生活随笔為你收集整理的hdu4784 不错的搜索( 买卖盐,要求整钱最多)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。