ZOJ 3812 We Need Medicine(牡丹江網路賽D題),zoj牡丹江

來源:互聯網
上載者:User

ZOJ 3812 We Need Medicine(牡丹江網路賽D題),zoj牡丹江
ZOJ 3812 We Need Medicine

題目連結

思路:dp[i][j][k]表示第i個物品,組成兩個值為j和k的狀態,這樣會爆掉,所以狀態需要轉化一下

首先利用滾動數組,可以省去i這維,然後由於j最大記錄到50,所以可以把狀態表示成一個位元s,轉化成dp[k] = s,表示組成k狀態能組成s,這樣空間複雜度就可以接受了,然後這題時限還可以,就這樣去轉移,然後記錄下路徑即可

代碼:

#include <cstdio>#include <cstring>#include <map>using namespace std;const int N = 200005;typedef unsigned long long ull;typedef long long ll;int t, n, q, W[N], T[N], ans[55][N];ull dp[N];map<ll, int> LOG;int main() {scanf("%d", &t);for (int i = 0; i < 52; i++)LOG[(1ULL<<i)] = i;while (t--) {scanf("%d%d", &n, &q);memset(dp, 0, sizeof(dp));memset(ans, 0, sizeof(ans));dp[0] = 1;for (int i = 1; i <= n; i++) { scanf("%d%d", &W[i], &T[i]);for (int j = 200000; j >= T[i]; j--) {ull tmp = dp[j];if (dp[j - T[i]] == 0) continue;dp[j] |= ((dp[j - T[i]])<<W[i]) & ((1ULL<<52) - 1);for (ull k = (tmp^dp[j]); k > 0; k &= (k - 1)) {ll x = k;ans[LOG[(x&(-x))]][j] = i;}}}int m, s;for (int i = 0; i < q; i++) {scanf("%d%d", &m, &s);if (!ans[m][s]) printf("No solution!\n");else {int v = ans[m][s];int bo = 0;while (v) {if (bo) printf(" ");else bo = 1;printf("%d", v);m -= W[v];s -= T[v];v = ans[m][s];}printf("\n");}}}return 0;}





聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.