如何優雅正確地通過interrupt方法中斷執行緒
一、題目理解
對於“考慮前\(i\)個物品,氧氣體積大於等於\(j\),氮氣體積大於等於\(k\)的方案”的集合(\(f[i][j][k]\))
可以按照“是否選擇第\(i\)個物品”來劃分
(1)若不選擇第\(i\)個物品
則就是“考慮前\(i-1\)個物品,氧氣體積大於等於\(j\) 並且氮氣體積大於等於\(k\)的方案”的集合 (\(f[i-1][j][k]\))
(2)若選擇了第\(i\)個物品
由於該集合均包含第\(i\)個物品
假設第\(i\)個物品有\(v_1\)個氧氣 \(v_2\)個氮氣
則除去第\(i\)個物品
就是考慮“從前\(i-1\)個物品選 氧氣體積大於等於\(j-v_1\)
若\(j-v_1\)小於零的話
就說明第\(i\)個物品提供的氧氣已經足夠
不需要從前\(i-1\)個物品中獲得任何氧氣
因此當\(j-v_1\)小於零的時候
直接按照\(0\)考慮即可
氮氣也一樣
二、求最大值最小值初始化總結
二維情況
1、體積至多\(j\),\(f[i,k] = 0\),\(0 <= i <= n, 0 <= k <= m\)(只會求價值的最大值)
2、體積恰好\(j\),
當求價值的最小值:\(f[0][0] = 0\), 其餘是\(INF\)
當求價值的最大值:\(f[0][0] = 0\), 其餘是\(-INF\)
3、體積至少\(j\),\(f[0][0] = 0\),其餘是\(INF\)(只會求價值的最小值)
一維情況
1、體積至多\(j\),\(f[i] = 0, 0 <= i <= m\)(只會求價值的最大值)
2、體積恰好\(j\),
當求價值的最小值:\(f[0] = 0\), 其餘是\(INF\)
當求價值的最大值:\(f[0] = 0\), 其餘是\(-INF\)
3、體積至少\(j\),\(f[0] = 0\),其餘是\(INF\)(只會求價值的最小值)
二、實現程式碼
#include <bits/stdc++.h> using namespace std; const int N = 1010; //氣缸的個數上限 const int M = 100; //需要的氧氣、氮氣上限值 int V1; //氧需要的量 int V2; //氮需要的量 int n; //氣缸的個數 int v1[N], v2[N], w[N];//第i個氣缸裡的氧和氮的容量及氣缸重量 int f[M][M]; //DP陣列 int main() { //讀入氧需要的量,氮需要的量,氣缸的個數 cin >> V1 >> V2 >> n; //讀入每個氣缸的氧和氮的容量及氣缸重量 for (int i = 1; i <= n; i++) cin >> v1[i] >> v2[i] >> w[i]; //求最小值要把除初始狀態以外的所有狀態初始化為+∞ memset(f, 0x3f, sizeof f); f[0][0] = 0; //因為採用了降維,所以體積都是倒著的~ for (int i = 1; i <= n; i++) for (int j = V1; j >= 0; j--) for (int k = V2; k >= 0; k--) f[j][k] = min(f[j][k], f[max(j - v1[i], 0)][max(k - v2[i], 0)] + w[i]); //輸出 printf("%d", f[V1][V2]); return 0; }