牵扯到选不选,而且选择达到的目标给的范围很小的时候,多半可以压缩状态。
而且这道题又问的是最少的包数,多半是压状dp。
算法:顺序枚举每一包糖果,然后枚举每一个状态,然后用糖果的状态去获得新状态,并且更新状态里的最少包数。
注意事项:
1、枚举状态的时候,一定要去掉不合法的状态。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<string>
#include<map>
#include<set>
#include<unordered_map>
#include<unordered_set>
#include<queue>
#include<stack>
#include<climits>
#define x first
#define y second
#define MP make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
int n, m, k;
int can[100][20], dp[1 << 20];
int main(void){
cin >> n >> m >> k;
memset(can, 0, sizeof(can));
memset(dp, -1, sizeof(dp));
for (int i = 0; i < n; ++i)
for (int j = 0; j < k; ++j){
cin >> can[i][j];
can[i][j]--;
}
int lim = 1 << m;
dp[0] = 0;
for (int i = 0; i < n; ++i){
int t = 0;
for (int j = 0; j < k; ++j) t |= (1 << can[i][j]);
for (int st = 0; st < lim; ++st){
if (dp[st] == -1) continue;
int nst = st | t;
if (dp[nst] == -1 || dp[nst] > dp[st] + 1) dp[nst] = dp[st] + 1;
// printf("(%d, %d) ", nst, dp[nst]);
}
// printf("\n");
}
cout << dp[lim - 1];
return 0;
}
比y总的好理解多了😂😂
泰裤辣
大佬牛逼呀
太牛了,感觉这题用状压dp再简单不过了
太强了
## 牛哇!
%%%
tql!!!!!!
tql!
妙啊