#include<bits/stdc++.h>
using namespace std;
int n, h, f[30][400], d[30], t[30], dp[30][400];
//dp[i][j]:前i个湖前j个单位时间的最大值
int main()
{
//freopen("in.txt","r",stdin);
while (~scanf("%d", &n) && n)
{
memset(f, 0, sizeof(f));
scanf("%d", &h);
h = h * 12;
for (int i = 1; i <= n; i++)
{
scanf("%d", &f[i][1]);
}
for (int i = 1; i <= n; i++)
{
scanf("%d", &d[i]);
}
for (int i = 2; i <= n; i++)
{
scanf("%d", &t[i]);
}
t[1] = 0;
for (int i = 1; i <= n; i++)
{
for (int k = 2; k <= h; k++)
{
if (f[i][k - 1] <= d[i]) break;
f[i][k] = f[i][k - 1] - d[i];
}
}
memset(dp, -1, sizeof(dp));
dp[0][0] = 0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j <= h; j++)
{
int sum = 0;
for (int k = 0; k <= h && dp[i][j] != -1; k++) //在第i个湖钓k个单位时间
{
if (j + t[i + 1] + k > h) break;
dp[i + 1][j + t[i + 1] + k] = max(dp[i][j] + sum, dp[i + 1][j + t[i + 1] + k]);
if (f[i + 1][k + 1] > 0) sum += f[i + 1][k + 1];
}
}
}
int mark = 1, MAX = 0;
for (int i = 1; i <= n; i++)
{
if (MAX < dp[i][h])
{
MAX = dp[i][h];
mark = i;
}
}
int MMAX = MAX;
for (int i = mark; i >= 2; i--)
{
int sum = 0, k;
for (k = 0; k <= h; k++)
{
if (MAX == sum + dp[i - 1][h - k - t[i]])
{
f[i][0] = k;
break;
}
sum = sum + f[i][k + 1];
}
h = h - t[i] - k;
MAX -= sum;
}
f[1][0] = h;
for (int i = 1; i < n; i++)
{
printf("%d, ", f[i][0] * 5);
}
printf("%d\n", f[n][0] * 5);
printf("Number of fish expected: %d\n\n", MMAX);
}
return 0;
}
//A
#include<bitsdc++.h>
using namespace std;
int N, nums=0;
int len[10010],dp[10010];
int main() {
cin >> N;
string s;
while (cin >> s) {
nums++;
len[nums] = len[nums - 1] + s.size();
}
memset(dp, 0, sizeof(dp));
for (int i = 1; i <= nums; i++) {
if (len[i] - len[i - 1] == N) {
dp[i] = dp[i - 1];
}
else {
dp[i] = dp[i - 1] + 500;
}
for (int j = i - 2; j >= 0; j--) {
int tot = i - j - 1;
int blanks = N - (len[i] - len[j]);
if (blanks < tot) continue;
int avg = blanks / tot;
int rmd = blanks % tot;
int s = rmd * (avg * avg) + (tot - rmd) * (avg - 1) * (avg - 1);
dp[i] = min(dp[i], dp[j] + s);
}
}
printf("Minimal badness is %d.\n", dp[nums]);
}
//B
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e4 + 10;
int nums[N]; // 存储数据
int dp[N]; // dp[i]表示以第i个位置的数为结尾的最长不下降子序列的长度
int ans = 0;
int main() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) scanf("%d", &nums[i]);
for (int i = 1; i <= n; i++) dp[i] = 1; // 初始化
for (int i = 1; i <= n; i++) {
for (int j = 1; j < i; j++) {
if (nums[j] < nums[i])
dp[i] = max(dp[j] + 1, dp[i]);
}
ans = max(dp[i], ans);
}
cout << ans << endl;
return 0;
}
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
int a[51][51][4];
cin >> n;
memset(a, 0, sizeof(a));
while (n)
{
for (int i = 1; i <= n; i++)
for (int j = 1; j <= i; j++)
{
cin >> a[i][j][1];
a[i][j][2] = a[i][j][1];
a[i][j][3] = 0;
}
for (int i = n - 1; i >= 1; i--)
for (int j = 1; j <= i; j++)
{
if (a[i + 1][j][2] > a[i + 1][j + 1][2])
{
a[i][j][2] = a[i + 1][j][2] + a[i][j][2];
a[i][j][3] = 0;
}
else
{
a[i][j][2] = a[i + 1][j + 1][2] + a[i][j][2];
a[i][j][3] = 1;
}
}cout << a[1][1][2] << endl;
int j = 1;
for (int i = 1; i <= n - 1; i++)
{
j = j + a[i][j][3];
}
cin >> n;
}
return 0;
}
//D
#include<bits/stdc++.h>
using namespace std;
#define MAXN 100000
int T[MAXN], dp[MAXN];
int main()
{
int len = 0;
while (scanf("%d",&T[len])!=EOF)
++len;
dp[0]=1;
int down_max=dp[0];
for (int i=1;i<len;i++)
{
dp[i]=1;
for (int j=0;j<i;j++)
{
if (T[j]>=T[i])
dp[i]=max(dp[i],dp[j]+1);
}
}
down_max=0;
for (int i=0;i<len;i++) down_max=max(down_max,dp[i]);
dp[0] = 1;
int up_max = dp[0];
for(int i=1; i<len; ++i)
{
//DP[i] = max{DP[k]+1,if(T[k]<T[i] && k<i)}
int max_index = i;
for(int k=0; k<i; ++k)
if(T[k]<T[i] &&
(max_index==i || dp[k]>dp[max_index]))
max_index = k;
if(max_index == i)
dp[i] = 1;
else
dp[i] = dp[max_index] + 1;
if(dp[i] > up_max)
up_max = dp[i];
}
printf("%d\n%d\n",down_max,up_max);
return 0;
}
//E
#include<bitsdc++.h>
using namespace std;
typedef pair <int, int> P;
int n, ans, f[5005];
P p[5005];
int main()
{
cin >> n;
for (int i = 1; i <= n; i++){
cin >> p[i].first >> p[i].second;
}
sort(p + 1, p + n + 1);
for (int i = 1; i <= n; i++){
f[i] = 1;
for (int j = 1; j < i; j++)
if (p[i].second >= p[j].second) { f[i] = max(f[i], f[j] + 1); }
ans = max(ans, f[i]);
}
cout << ans << endl;
return 0;
}
//F
#include<bitsdc++.h>
using namespace std;
int n, ans, f[205],rec[205],a[205];
int c[205][205];
int main()
{
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
int x, y;
while (cin >> x >> y && x || y) {
c[x][y] = 1;
}
f[n] = a[n];
for (int i = n - 1; i >= 1; i--) {
int t = 0;
int maxn = 0;
for (int j = i + 1; j <= n; j++) {
if (c[i][j] == 1 && f[j] > maxn) {
maxn = f[j];
t = j;
}
}
f[i] = a[i] + maxn;
rec[i] = t;
// cout << rec[i] << " " << i << endl;
}
int s = 1;
for (int i = 1; i <= n; i++) {
if (f[i] > ans){
ans = f[i];
s = i;
}
}
while (rec[s] != 0) {
cout << s << "-";
s = rec[s];
}
cout << s << endl;
cout << ans << endl;
return 0;
}
//H
#include <bits/stdc++.h>
using namespace std;
string s,t;
int dp[105][105];
int main()
{
while (cin >> s >> t)
{
memset(dp, 0, sizeof(dp));
int a = s.size();
int b = t.size();
for(int i=1;i<=a;i++)
for (int j = 1; j <= b; j++)
{
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
if (s[i - 1] == t[j - 1])
dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + 1);
}
cout << dp[a][b] << endl;
}
return 0;
}
//I
#include<bits/stdc++.h>
using namespace std;
int n, v, c[5050], w[5050], f[5050];
inline int read()
{
int x = 0;
char c = getchar();
while (c < '0' || c>'9') c = getchar();
while (c >= '0' && c <= '9')
{
x = x * 10 + c - '0';
c = getchar();
}
return x;
}
int main()
{
n = read(); v = read();
for (int i = 1; i <= n; i++)
{
c[i] = read();
w[i] = read();
}
memset(f, 0, sizeof(f));//用给f赋一个较小值
for (int i = 1; i <= n; i++)//从第一行推到第n行,最后一次保存的就是第n行的f信息
{
for (int j = v; j >= c[i]; j--)//从大到小推,注意容量要大于等于物体的体积
{
f[j] = max(f[j], f[j - c[i]] + w[i]);
}
}
printf("%d", f[v]);//输出前n个物品放入v容量背包的最大价值
return 0;
}
//J
#include<bitsdc++.h>
using namespace std;
int w[500000], v[500000], dp[5000000];
int main() {
int m, n;
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> w[i] >> v[i];
}
for (int i = 1; i <= m; i++) {
for (int j = n; j >= 0; j--) {
if (j >= w[i])dp[j] = max(dp[j], dp[j - w[i]] + v[i]);
}
}
cout << dp[n] << endl;
return 0;
}
//K
#include <bitsdc++.h>
using namespace std;
int f[201], n;
bool pri[201] = { 0 };
void add(int x){
for (int i = x; i <= 200; i++) {
f[i] += f[i - x];
}
}
int main(){
f[0] = 1, f[1] = 0;
for (int i = 2; i <= 200; i++) {
if (!pri[i]) {
add(i);
for (int j = i * i; j <= 200; j += i) {
pri[j] = 1;
}
}
}
while (cin >> n) {
cout << f[n] << endl;
}
return 0;
}
//L
问题 M: 完全背包问题
内存限制:128 MB时间限制:1.000 S评测方式:文本比较命题人:外部导入提交:286解决:122题目描述
设有n种物品,每种物品有一个重量及一个价值。但每种物品的数量是无限的,同时有一个背包,最大载重量为M,今从n种物品中选取若干件(同一种物品可以多次选取),使其重量的和小于等于M,而价值的和为最大。输入
第一行:两个整数,M(背包容量,M<=200)和N(物品数量,N<=30);
第2..N+1行:每行二个整数Wi,Ci,表示每个物品的重量和价值。
输出
仅一行,一个数,表示最大总价值。样例输入 复制
10 4 2 1 3 3 4 5 7 9
样例输出 复制
max=12
#include<bits/stdc++.h>
using namespace std;
int n, m, f[10005];
struct node{
int w;
int c;
}d[105];
int main()
{
scanf("%d%d", &m, &n);
for (int i = 1; i <= n; i++)
{
scanf("%d%d", &d[i].w, &d[i].c);
}
for (int i = 1; i <= n; i++)
for (int v = 1; v <=m; v++)
{
if (d[i].w <= v)
f[v] = max(f[v], f[v - d[i].w] + d[i].c);
/*if (v < d[i].w) f[i][v] = f[i - 1][v];
else
if (f[i - 1][v] > f[i][v - d[i].w] + d[i].c) f[i][v] = f[i - 1][v];
else
f[i][v] = f[i][v - d[i].w] + d[i].c;*/
}
printf("max=%d\n", f[m]);
return 0;
}
//M
#include <bits/stdc++.h>
using namespace std;
int n, m, dp[1005][1005], v[1005][1005];
int main()
{
cin >> m >> n;
for (int i = 0; i <= m; i++)
for (int j = 1; j <= n; j++)
{
cin >> v[j][i];
}
for (int i = 0; i <= m; i++)
{
dp[1][i] = v[1][i];
}
for (int i = 0; i <= n; i++)
for (int j = 1; j <= m; j++)
{
int maxn = 0;
//find
for (int xk = 0; xk <= j; xk++)
maxn = max(maxn, v[i][xk] + dp[i - 1][j - xk]);
dp[i][j] = maxn;
}
cout << dp[n][m] << endl;
return 0;
}
问题 O: 0/1背包
题目描述
一个旅行者有一个最多能用m公斤的背包,现在有n件物品,它们的重量分别是W1,W2,...,Wn,它们的价值分别为C1,C2,...,Cn.若每种物品只有一件求旅行者能获得最大总价值。
输入
w第一行:两个整数,M(背包容量,M<=200)和N(物品数量,N<=30);
w 第2..N+1行:每行二个整数Wi,Ci,表示每个物品的重量和价值。
输出
仅一行,一个数,表示最大总价值。
样例输入 复制
10 4 2 1 3 3 4 5 7 9
样例输出 复制
12
#include<bits/stdc++.h>
using namespace std;
int n, m, f[10005];
struct node{
int w;
int c;
}d[105];
int main()
{
scanf("%d%d", &m, &n);
for (int i = 1; i <= n; i++)
{
scanf("%d%d", &d[i].w, &d[i].c);
}
for (int i = 1; i <= n; i++)
for (int v = m; v > 0; v--)
{
if (d[i].w <= v)
f[v] = max(f[v], f[v - d[i].w] + d[i].c);
}
printf("%d\n", f[m]);
return 0;
}
//O
问题 P: 庆功会
题目描述
为了庆贺班级在校运动会上取得全校第一名成绩,班主任决定开一场庆功会,为此拨款购买奖品犒劳运动员。期望拨款金额能购买最大价值的奖品,可以补充他们的精力和体力。输入
第一行二个数n(n<=500),m(m<=6000),其中n代表希望购买的奖品的种数,m表示拨款金额。
接下来n行,每行3个数,v、w、s,分别表示第I种奖品的价格、价值(价格与价值是不同的概念)和购买的数量(买0件到s件均可),其中v<=100,w<=1000,s<=10。
输出
第一行:一个数,表示此次购买能获得的最大的价值(注意!不是价格)。
样例输入 复制
5 1000 80 20 4 40 50 9 30 50 7 40 30 6 20 20 1
样例输出 复制
1040
#include<bits/stdc++.h>
using namespace std;
int v[6002], w[6002], s[6002], f[6002];
int n, m;
int max(int x, int y)
{
if (x < y) return y;
else return x;
}
int main()
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
scanf("%d%d%d", &v[i], &w[i], &s[i]);
for (int i = 1; i <= n; i++)
for (int j = m; j >= 0; j--)
for (int k = 0; k <= s[i]; k++)
{
if (j - k * v[i] < 0) break;
f[j] = max(f[j], f[j - k * v[i]] + k * w[i]);
}
printf("%d", f[m]);
return 0;
}
//P
问题 Q: 混合背包
题目描述
一个旅行者有一个最多能用V公斤的背包,现在有n件物品,它们的重量分别是W1,W2,...,Wn,它们的价值分别为C1,C2,...,Cn。有的物品只可以取一次(01背包),有的物品可以取无限次(完全背包),有的物品可以取的次数有一个上限(多重背包)。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
输入
第一行:二个整数,V(背包容量,V<=200),N(物品数量,N<=30);
第2..N+1行:每行三个整数Wi,Ci,Pi,前两个整数分别表示每个物品的重量,价值,第三个整数若为0,则说明此物品可以购买无数件,若为其他数字,则为此物品可购买的最多件数(Pi)。输出
仅一行,一个数,表示最大总价值。
样例输入 复制
10 3 2 1 0 3 3 1 4 5 4
样例输出 复制
11
#include<bits/stdc++.h>
using namespace std;
int main() {
int V, n;
scanf("%d%d", & V, & n);
int w[n], c[n], p[n];
for (int i = 0; i < n; i++) {
scanf("%d%d%d", & w[i], & c[i], & p[i]);
}
int dp[V + 1000] = {
0
};
int ans = 0;
for (int i = 0; i < n; i++) {
if (p[i] == 0) { //p[i]等于0时,转化为完全背包求解
for (int j = w[i]; j <= V; j++) {
dp[j] = max(dp[j], dp[j - w[i]] + c[i]);
ans = max(ans, dp[j]);
}
}
else {
for (int j = V; j >= w[i]; j--) {
for (int l = 1; l <= p[i] && l * w[i] <= j; l++) {
dp[j] = max(dp[j], dp[j - l * w[i]] + l * c[i]);
ans = max(ans, dp[j]);
}
}
}
}
printf("%d", ans);
return 0;
}
//Q
#include<bitsdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
int a[1005], b[1005], c[1005], dp[1005][1005];
int main() {
int m, n, k;
cin >> m >> n >> k;
for (int i = 1; i <= k; i++) {
cin >> a[i] >> b[i] >> c[i];
}
memset(dp, INF, sizeof(dp));
dp[0][0] = 0;
for (int i = 1; i <= k; i++) {
for (int x = m; x >= 0; x--) {
for (int y = n; y >= 0; y--) {
if (dp[x][y] == INF) continue;
int u = min(m, x + a[i]);
int v = min(n, y + b[i]);
dp[u][v] = min(dp[u][v], dp[x][y] + c[i]);
}
}
}
cout << dp[m][n] << endl;
return 0;
}
//R
#include<bitsdc++.h>
using namespace std;
int w[1000], c[1000], p[1000],dp[100000];
struct A {
int a[1005];
int b[1005];
int len = 0;
}t[1000];
int main() {
int V, N, T, l = 0;
cin >> V >> N >> T;
for (int i = 1; i <= N; i++) {
cin >> w[i] >> c[i] >> p[i];
l = ++t[p[i]].len;
t[p[i]].a[l] = w[i];
t[p[i]].b[l] = c[i];
}
for (int i = 1; i <= T; i++) {
for (int j = V; j >= 0; j--) {
for (int k = 1; k <= t[i].len; k++) {
if (j >= t[i].a[k]) {
dp[j] = max(dp[j], dp[j - t[i].a[k]] + t[i].b[k]);
}
}
}
}
cout << dp[V] << endl;
return 0;
};
//S
#include<bitsdc++.h>
using namespace std;
long long v[100005], dp[100005],ans;
int main() {
long long m, n;
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> v[i];
}
dp[0] = 1;
for (int i = 1; i <= n; i++){
for (int j = v[i]; j <= m; j++) {
dp[j] += dp[j - v[i]];
}
}
cout << dp[m] << endl;
}
//T
#include<bits/stdc++.h>
using namespace std;
int n, sum, maxn = -INT16_MAX, a[100001];
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
sum = 0;
for (int i = 1; i <= n; i++)
{
sum += a[i];
if (sum > maxn)
maxn = sum;
if (sum < 0)
sum = 0;
}
cout << maxn <<endl;
return 0;
}
//最后一个