版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
1、1068 Find More Coins (30 分)
题目大意:给出商品价值,给出硬币数量、面值,输出能购买商品的最小硬币组合;
首先对输入进行排序,大前小后,这样就在计算时,让较小的数列替代较大数列;用01背包问题解法,先计算最大的模块占去空间后,剩下的空间所放置的最大价值;模块价值逐渐变小,然后由此循环、替换求出最大价值的新值;在求出新值的同时对已选取的x做标记,方便后续引用;
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
bool chosen[10010][110];
int dp[10010], w[10010];
bool cmp1(int a, int b) {
return a > b;
}
int main() {
int m, n;
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++) {
scanf("%d", &w[i]);
}
sort(w, w + n, cmp1);
for (int i = 0; i < n; i++)
for (int j = m; j >= w[i]; j--) {
if (dp[j] <= dp[j - w[i]] + w[i]) {
dp[j] = dp[j - w[i]] + w[i];
chosen[i][j] = true;
}
}
在进行相关序号输出时,从大至小配合每个模块的价值输出;
if (dp[m] != m)printf("No Solution");
else {
vector<int> u;
int index = n-1, v = m;
while (v > 0) {
if (chosen[index][v] == true) {
u.push_back(w[index]);
v -= w[index];
}
index--;
}
for (int i = 0; i < u.size(); i++) {
if (i != 0) printf(" ");
printf("%d", u[i]);
}
}
return 0;
}
2、1045 Favorite Color Stripe (30 分)
题目大意:给出一组规定的数列,在一个给出的长序列中找出一个按给定序列的按序最长子序列(可分隔、重复),输出长度。
对于给出的数列,用数组储存其位置;在输入时先筛选去给定数列以外的数字,在余下的数仍旧使用位置来储存,使用动态规划,从短数列到长数列,若当前数列的数尾位置排在遍历的数之后,则之前遍历得到的dp在现在遍历的数的dp再加上1比较,取最大值;
#include<algorithm>
#include<iostream>
using namespace std;
int dp[10010] = { 0 };
int main() {
int n, z, fav[220] = { 0 }, x;
scanf("%d%d",&z, &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &x);
fav[x] = i;
}
int maxn = 0, y, m, num = 0, a[10010] = { 0 };
scanf("%d", &y);
for (int i = 0; i < y; i++) {
scanf("%d", &m);
if (fav[m] > 0) {
a[num] = fav[m];
num++;
}
}
for (int i = 0; i < num; i++) {
dp[i] = 1;
for (int j = 0; j < i; j++) {
if (a[i] >= a[j]) {
dp[i] = max(dp[i], dp[j] + 1);
}
}
maxn = max(dp[i], maxn);
}
printf("%d", maxn);
}