1、动态转移选主件元件,对于dp[j],表示选则主件,和若干附加,不超过j元的最大价值
2、动态转移有四种情况:
(1)不选主件
(2)选主件,不选附件
(3)选主件,选一个附件(在花费允许的情况下)
(4)选主件,选两个附件(一个主件最多两个附件)(在花费允许的情况下)
- dp[j] = max(dp[j], dp[j-mainw[i]]+mainv[i]);
- if (j-mainw[i]>=secw[i][1])
- dp[j] = max(dp[j], dp[j-mainw[i]-secw[i][1]]+mainv[i]+secv[i][1]);
- if (j-mainw[i]>=secw[i][2])
- dp[j] = max(dp[j], dp[j-mainw[i]-secw[i][2]]+mainv[i]+secv[i][2]);
- if (j-mainw[i]>=secw[i][2]+secw[i][1])
- dp[j] = max(dp[j], dp[j-mainw[i]-secw[i][2]-secw[i][1]]+mainv[i]+secv[i][2]+secv[i][1]);
用一个数组专门存主件的价值和花费,另一个二维数组存附件(对应主件)的价值花费
3、因为是一维的动态转移,因此我们将花费遍历倒过来
- # include
- using namespace std;
- int n, m;
- int mainw[70], mainv[70];
- int secw[70][5], secv[70][5];
- int dp[32000+10];
- int main()
- {
- cin>>n>>m;
- for (int i=1; i<=m; i++)
- {
- int v, p, q;
- cin>>v>>p>>q;
- if (!q)
- {
- mainw[i] = v;
- mainv[i] = p*v;
- }
- else
- {
- secw[q][0]++;
- secw[q][secw[q][0]] = v;
- secv[q][secw[q][0]] = v*p;
- }
- }
- for (int i=1; i<=m; i++)
- {
- for (int j=n; mainw[i]&&j>=mainw[i]; j--)
- {
- dp[j] = max(dp[j], dp[j-mainw[i]]+mainv[i]);
- if (j-mainw[i]>=secw[i][1])
- dp[j] = max(dp[j], dp[j-mainw[i]-secw[i][1]]+mainv[i]+secv[i][1]);
- if (j-mainw[i]>=secw[i][2])
- dp[j] = max(dp[j], dp[j-mainw[i]-secw[i][2]]+mainv[i]+secv[i][2]);
- if (j-mainw[i]>=secw[i][2]+secw[i][1])
- dp[j] = max(dp[j], dp[j-mainw[i]-secw[i][2]-secw[i][1]]+mainv[i]+secv[i][2]+secv[i][1]);
- }
- }
- cout<
-
-
- return 0;
- }
NC14699 队伍配置
题目链接
关键点:
1、对于从者的选择,我们只考虑选择5个,对于礼装,我们考虑选择不超过从者的个数
2、选择前i个从者和前j个礼装,我们可以利用滚动数组减去一维
3、设dp[i][j][k],表示在cost=i的前提下,选择j个从者,k个礼装的最大价值
4、我们可以先处理礼装(k)=0,情况下,最多选择5个从者的最大价值,注意cost要倒过来遍历(少了一维)
5、然后在输入礼装数据时,在遍历礼装的个数
完整代码:
- # include
- using namespace std;
- int dp[140][10][310];//代表i的cost下,选j个从者,装备k个礼装的最大价值
- int ans, n, m, d;
- int main()
- {
- cin>>n>>m>>d;
- for (int i=1; i<=n; i++)
- {
- int x, y;
- cin>>x>>y;
- for (int i=d; i>=y; i--)
- {
- for (int j=1; j<=5; j++)
- {
- dp[i][j][0] = max(dp[i][j][0], dp[i-y][j-1][0]+x);
- ans = max(dp[i][j][0], ans);
- }
- }
- }
- for (int i=1; i<=m; i++)
- {
- int x, y;
- cin>>x>>y;
- for (int i=d; i>=y; i--)
- {
- for (int j=1; j<=5; j++)
- {
- for (int k=1; k<=j; k++)
- {
- dp[i][j][k] = max(dp[i][j][k], dp[i-y][j][k-1]+x);
- ans = max(dp[i][j][k], ans);
- }
- }
- }
- }
- cout<
-
- return 0;
- }
NC235951 草药大师
题目链接
关键点:
1、因为最大的时间上限很大,直接遍历会超时,这里利用map来遍历,mp[i] = j,表示时间为i的情况下,最多采集的价值为j。可以发现在背包中,每次被更新的时间只会在所有草药(小于限定的s)中排列加减得到。
2、一维的map来代表dp数组,要将map倒着遍历
3、最后在所有的时间中取最大值即可
4、记得要初始化dp[0] = 0;
完整代码:
- # include
- using namespace std;
- typedef long long ll;
- ll n, s;
- map
mp; - ll t[110], v[110];
- int main()
- {
- cin>>n>>s;
- for (int i=1; i<=n; i++)
- {
- cin>>t[i]>>v[i];
- }
- mp[0] = 0;
- for(int i=1;i<=n;i++){
- for(auto it=rbegin(mp);it!=rend(mp);it++){
- if(it->first+t[i]<=s)
- mp[it->first+t[i]]=max(mp[it->first+t[i]],mp[it->first]+v[i]);
- }
- }
- ll ans=0;
- for (auto it=mp.begin(); it!=mp.end(); it++)
- ans = max(it->second, ans);
- cout<
-
- return 0;
- }
-
相关阅读:
Docker export导出容器,重新运行导出的容器
基于Django框架的零食商城系统之Python毕设选题推荐
呕血回顾一次提高接口并发的经历,很实用
MongoDB的详细安装教程
Java 21 新特性:Record Patterns
Pytorch-CNN-CIFAR10
15 软专
QStatusBar
位运算相关
i.MX6ULL驱动开发 | 34 - 基于SPI框架驱动spi lcd(st7789)
-
原文地址:https://blog.csdn.net/m0_60531106/article/details/126651810