kuangbin带你飞:点击进入新世界

文章目录

1.Max Sum Plus Plus

原题链接:传送门

2.Ignatius and the Princess IV

原题链接:传送门

思路:hash存储(感觉和dp没啥关系啊。。)

#include<bits/stdc++.h>
using namespace std;
map<int, int>mp; int n, t;
int main() {
freopen("in.txt", "r", stdin);
ios::sync_with_stdio(false); cin.tie(0);
while (cin >> n) {
mp.clear();
for (int i = 0; i < n; ++i) { cin >> t; mp[t]++; }
for (auto &p : mp) {
if (p.second >= (n + 1) / 2) { cout << p.first << endl; break; }
}
}
}

3.Monkey and Banana

原题链接:传送门

解析:对于所给的砖块可以有6种组合(即:长宽高打乱)所以最终的 $ index = 6 * n$

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1000;
struct node {
int l, r, w;//长宽高
}a[maxn]; int n, r, w, l; bool cmp(node &a, node &b) {
if (a.l == b.l)return a.r < b.r;
return a.l < b.l;
} int dp[maxn]; int main() {
freopen("in.txt", "r", stdin);
ios::sync_with_stdio(false); cin.tie(0);
int Case = 1;
while (cin >> n && n) {
int index = 1;
for (int i = 0; i < n; ++i) {
cin >> l >> r >> w;
a[index].l = l, a[index].r = r, a[index++].w = w;
a[index].l = r, a[index].r = l, a[index++].w = w;
a[index].l = w, a[index].r = r, a[index++].w = l;
a[index].l = l, a[index].r = w, a[index++].w = r;
a[index].l = r, a[index].r = w, a[index++].w = l;
a[index].l = w, a[index].r = l, a[index++].w = r;
}
sort(a + 1, a + index + 1,cmp);//根据长宽排序
memset(dp, 0,sizeof dp);
int ans = 0;
for(int i = 1;i <= index;++i)
for (int j = 1; j <= index; ++j) {
if (a[i].r < a[j].r && a[i].l < a[j].l)
dp[j] = max(dp[j], dp[i] + a[j].w), ans = max(ans, dp[j]);
}
cout << "Case " << Case++ << ": maximum height = " << ans << endl;
}
}

4.Doing Homework (状态压缩DP)

HDU - 1074

解析:

先大致说说状态压缩,假设有三门作业a,b,c

那么,abc都做完即111,111可由101,110,011任意一个来得到。而101可以从100或者001来得到,这就是状态压缩dp的一个基本的状态转移。

#include<bits/stdc++.h>
using namespace std;
const int N = 16;
struct Node
{
char str[109];
int want, need;
}node[N]; struct DP
{
int now, sum, next, pos;
}dp[1 << N]; void put_ans(int x)
{
if (dp[x].next != -1)
{
put_ans(dp[x].next);
printf("%s\n", node[dp[x].pos].str);
}
} int main()
{
freopen("in.txt", "r", stdin);
int T;
scanf("%d", &T);
while (T--)
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%s%d%d", node[i].str, &node[i].want, &node[i].need);
dp[0].now = dp[0].sum = 0;
dp[0].next = dp[0].pos = -1;
int m = (1 << n) - 1;
for (int i = 1; i <= m; i++)
{
dp[i].sum = 0x3f3f3f3f;
for (int j = 0; j < n; j++)
{
if ((1 << j) & i)
{
int k = i - (1 << j);
int v = dp[k].now + node[j].need - node[j].want;
v = max(v, 0);
if (dp[i].sum >= dp[k].sum + v)
{
dp[i].sum = dp[k].sum + v;
dp[i].now = dp[k].now + node[j].need;
dp[i].next = k;
dp[i].pos = j;
}
}
}
}
printf("%d\n", dp[m].sum);
put_ans(m);
}
return 0;
}
// update 2022.2.28
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 16;
struct node {
string str;
int want, need;
} a[N]; struct DP {
int now, sum, next, pos;
} dp[1 << N]; void put_ans(int x) {
if (dp[x].next != -1) {
put_ans(dp[x].next);
cout << a[dp[x].pos].str << "\n";
}
} int n, t; int main() {
ios::sync_with_stdio(false), cin.tie(nullptr);
cout << fixed << setprecision(20);
cin >> t;
while (t--) {
cin >> n;
for (int i = 0; i < n; i += 1) cin >> a[i].str >> a[i].want >> a[i].need;
dp[0].now = dp[0].sum = 0;
dp[0].next = dp[0].pos = -1;
int m = (1 << n) - 1;
for (int i = 1; i <= m; i += 1) {
dp[i].sum = 0x3f3f3f3f;
for (int j = 0; j < n; j += 1) {
if ( (1 << j) & i ) {
int k = i - (1 << j);
int v = dp[k].now + a[j].need - a[j].want;
v = max(v, 0);
if (dp[i].sum >= dp[k].sum + v) {
dp[i].sum = dp[k].sum + v;
dp[i].now = dp[k].now + a[j].need;
dp[i].next = k;
dp[i].pos = j;
}
}
}
}
cout << dp[m].sum << "\n";
put_ans(m);
}
}

5.Super Jumping! Jumping! Jumping!

HDU - 1087

解析:注意题目是严格上升子序列并不是连续上升子序列(导致我写错了转移方程2333)

#include<bits/stdc++.h>
using namespace std; #define ms(a,b) (a,b,sizeof a) const int maxn = 1e3 + 10;
int dp[maxn], a[maxn];
int n; int main() {
freopen("in.txt", "r", stdin);
ios::sync_with_stdio(false); cin.tie(0);
while (cin >> n && n) {
ms(dp, 0);
for (int i = 0; i < n; ++i)
cin >> a[i], dp[i] = a[i]; int ans = 0; for (int i = 0; i < n; ++i)
{
for (int j = i + 1; j < n; ++j)
{
if (a[j] > a[i])
dp[j] = max(dp[j], dp[i] + a[j]);
}
ans = max(ans, dp[i]);
}
cout << ans << endl;
}
}

同样是LIS模板题:最少拦截系统:传送门

6.Piggy-Bank

HDU - 1114

每种硬币的数量都不限制,因此是个完全背包。初始化dp数组时需注意,因为求的最小,且题目的意思是恰好装满,所以dp数组初始化为INF,但dp[0] = 0,意为此时只有容量为0 的背包可以在什么也不装且价值为0 的情况下被“恰好装满”,其它容量的背包均没有合法的解,属于未定义的状态(背包九讲)

#include<bits/stdc++.h>
using namespace std;
const int N = 10010;
const int inf = 0x3f3f3f3f;
int dp[N], v[N], w[N];
int n, t, e, f;
int main() {
//freopen("in.txt","r",stdin);
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin >> t; while (t--) {
cin >> e >> f;
int W = f - e;
cin >> n;
for (int i = 1; i <= n; ++i)cin >> v[i] >> w[i];
memset(dp, 0x3f, sizeof dp);
dp[0] = 0;
for (int i = 1; i <= n; ++i)
for (int j = w[i]; j <= W; ++j)
dp[j] = min(dp[j], dp[j - w[i]] + v[i]);
if(dp[W] == inf )printf("This is impossible.\n");
else printf("The minimum amount of money in the piggy-bank is %d.\n", dp[W]);
}
}

7.免费馅饼 (数塔 + 逆向DP)

HDU - 1176

思路:

如果把时间轴看成行数,每个点在这个时间上获得的饼数看成列数,那么a[i][j]表示在时间为i时j点获得的饼,如果把图画出来就可以发现这其实是一道数塔题。

因为要处理相邻两边,下标为0的时候不好处理,所以把位置+1;

既然是数塔题,那么显而易见:

$ dp[i][j] = max({dp[i + 1][j - 1],dp[i + 1][j], dp[i + 1][j + 1]}) + a[i][j];$

这道题再升级一下就是加上高度的。POJ 1661Help Jimmy(逆向DP Or 记忆化搜索 Or 最短路径)

#include<bits/stdc++.h>
using namespace std;
#define ms(a,b) memset(a,b,sizeof a);
const int maxn = 1e5 + 50;
int t, x, y;
int a[maxn][15], dp[maxn][15];
int main() {
//freopen("in.txt","r",stdin);
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
while (cin >> t && t) {
ms(dp, 0);
ms(a, 0);
int e = 0;
for (int i = 0; i < t; ++i) { cin >> x >> y; a[y][++x]++; e = max(e, y); }
for (int i = e; i >= 0; i--)
for (int j = 1; j <= 11; j++)
dp[i][j] = max({dp[i + 1][j - 1],dp[i + 1][j], dp[i + 1][j + 1]}) + a[i][j];
cout << dp[0][6] << endl;
}
}

8.Tickets

HDU - 1260

思路:

  1. 只能两个人一起买票,那么递推式很容易推出来:
  2. dp[i]=min(dp[i-1]+a[i] , dp[j-2]+b[i])
  3. 此处为单独买,和前一个人的买的较大值
  4. dp[n]为答案 。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2010;
int a[maxn], b[maxn], dp[maxn];
int n, m, r, t = 0;
int main() {
//freopen("in.txt","r",stdin);
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
while (cin>>t) {
while (t--) {
cin >> n;
for (int i = 1; i <= n; ++i)cin >> a[i];
for (int i = 2; i <= n; ++i)cin >> b[i];
dp[1] = a[1];
for (int i = 2; i <= n; ++i)dp[i] = min(dp[i - 1] + a[i], dp[i - 2] + b[i]);
int h = 8, mi = 0, sec = 0;
sec += dp[n];
mi += sec / 60 % 60;
h += sec / 3600;
sec %= 60;
printf("%02d:%02d:%02d ", h, mi, sec);
if (h >= 12) printf("pm\n");
else printf("am\n");
}
}
}

9.FatMouse's Speed

HDU - 1160

#include<bits/stdc++.h>
using namespace std;
struct Mouse
{
int id;
int speed;
int weight;
int pre;
int dp;
} mouse[10010]; int cmp(Mouse a, Mouse b)
{
if (a.weight == b.weight)
{
return a.speed > b.speed;
}
return a.weight < b.weight;
}
int dfs(int p)
{
//printf("@%d %d\n",p,mouse[p].pre);
if (p == -1) return 0;
dfs(mouse[p].pre);
printf("%d\n", mouse[p].id);
return 0;
}
int main()
{
int i = 0;
while (~scanf("%d%d", &mouse[i].weight, &mouse[i].speed))
{
mouse[i].id = i + 1;
mouse[i].pre = -1;
mouse[i].dp = 1;
i++;
}
sort(mouse, mouse + i, cmp);
int n = i;
mouse[0].dp = 1;
int ans = 1;
int p = 0;
for (int i = 1; i < n; i++)
{
for (int j = 0; j < i; j++)
{
if (mouse[i].weight > mouse[j].weight && mouse[i].speed < mouse[j].speed)
{
if (mouse[j].dp + 1 > mouse[i].dp)
{
mouse[i].dp = mouse[j].dp + 1;
mouse[i].pre = j;
}
}
}
if (mouse[i].dp > ans)
{
ans = mouse[i].dp;
p = i;
}
}
/*
for(int i=0;i<n;i++)
{
printf("id:%d w:%d s:%d pre:%d dp:%d\n",mouse[i].id,mouse[i].weight,mouse[i].speed,mouse[i].pre,mouse[i].dp);
}*/
printf("%d\n", ans);
dfs(p);
return 0;
}

10.Jury Compromise

POJ - 1015

11.FatMouse and Cheese

HDU - 1078

思路:

  1. dp[i]日常表示前i个数的最大价值。
  2. 这题主要是把数据处理一下,把结束时间加上r,然后记得把结构体排序。
  3. 那么就转化成一维的最大子序列和了。
  4. dp[i]=max(dp[i],dp[k]+a[j].w) when a[k].r<=a[i].l&&l>k
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e3 + 10;
int dp[maxn][maxn], a[maxn][maxn];
int nx[] = { 0,1,0,-1 };
int ny[] = { 1,0,-1,0 };
int n, m, r, t = 1;
int dfs(int x, int y) {
if (dp[x][y]) return dp[x][y];
int mx = 0;
for (int i = 1; i <= m; ++i) {
for (int j = 0; j < 4; ++j) {
int xx = x + nx[j] * i, yy = y + ny[j] * i;
if (a[x][y] < a[xx][yy] && xx>0 && yy > 0 && xx <= n && yy <= n)
mx = max(dfs(xx, yy), mx);
}
}
return dp[x][y] = a[x][y] + mx;
}
int main() {
//freopen("in.txt","r",stdin);
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
while (cin >> n >> m && n != -1 &&m != -1) {
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
cin >> a[i][j];
memset(dp, 0, sizeof dp);
cout << dfs(1, 1) << endl;
}
}

12.Phalanx

HDU - 2859

思路:

  1. 最大对称子矩阵,左下角到右上角为对称轴。
  2. 枚举每一个点,如果相同,把行数x向上扩展,列数y相右扩展。
  3. \(dp[i][j]=min(dp[i-1][j+1],i-x-1)+1 \quad when\quad a[i][j+1]==a[i-1][j]\)
#include<bits/stdc++.h>
using namespace std;
#define ms(a,b) memset(a,b,sizeof a);
const int N = 1010;
char a[N][N];
int dp[N][N];
int n;
int main() {
freopen("in.txt","r",stdin);
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
while (cin >> n && n) {
ms(dp, 0);
int ans = 1;
for (int i = 1; i <= n; ++i)for (int j = 1; j <= n; ++j)cin >> a[i][j];
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) {
dp[i][j] = 1;
int x = i, y = j;
while (a[i][y] == a[x][j])x--, y++;
if(a[i][j + 1] == a[i - 1][j])
dp[i][j] = min(dp[i - 1][j + 1], i - x - 1) + 1;
ans = max(ans, dp[i][j]);
}
cout << ans << endl;
}
}

[kuangbin带你飞]专题十二 基础DP1 题解+总结的更多相关文章

  1. 【算法系列学习】[kuangbin带你飞]专题十二 基础DP1 G - 免费馅饼

    https://vjudge.net/contest/68966#problem/G 正解一: http://www.clanfei.com/2012/04/646.html #include< ...

  2. 【算法系列学习】DP和滚动数组 [kuangbin带你飞]专题十二 基础DP1 A - Max Sum Plus Plus

    A - Max Sum Plus Plus https://vjudge.net/contest/68966#problem/A http://www.cnblogs.com/kuangbin/arc ...

  3. [kuangbin带你飞]专题十二 基础DP1

            ID Origin Title   167 / 465 Problem A HDU 1024 Max Sum Plus Plus   234 / 372 Problem B HDU 1 ...

  4. 【算法系列学习】[kuangbin带你飞]专题十二 基础DP1 F - Piggy-Bank 【完全背包问题】

    https://vjudge.net/contest/68966#problem/F http://blog.csdn.net/libin56842/article/details/9048173 # ...

  5. 【算法系列学习】[kuangbin带你飞]专题十二 基础DP1 E - Super Jumping! Jumping! Jumping!

    https://vjudge.net/contest/68966#problem/E http://blog.csdn.net/to_be_better/article/details/5056334 ...

  6. 【算法系列学习】状压dp [kuangbin带你飞]专题十二 基础DP1 D - Doing Homework

    https://vjudge.net/contest/68966#problem/D http://blog.csdn.net/u010489389/article/details/19218795 ...

  7. 【算法系列学习】[kuangbin带你飞]专题十二 基础DP1 C - Monkey and Banana

    https://vjudge.net/contest/68966#problem/C [参考]http://blog.csdn.net/qinmusiyan/article/details/79862 ...

  8. 【算法系列学习】[kuangbin带你飞]专题十二 基础DP1 B - Ignatius and the Princess IV

    http://www.cnblogs.com/joeylee97/p/6616039.html 引入一个cnt,输入元素与上一个元素相同,cnt增加,否则cnt减少,当cnt为零时记录输入元素,因为所 ...

  9. [ An Ac a Day ^_^ ] [kuangbin带你飞]专题十二 HDU 1176 免费馅饼

    题意: 中文题意不解释…… 思路: 先把x,T存到矩阵里 然后像数塔一样从最底层走一边就行了 dp[i][j]代表在时间为j时 第i个位置最多能吃到多少个馅饼 最后输出第0时刻的5位置的馅饼数量就好了 ...

  10. [kuangbin带你飞]专题十四 数论基础

            ID Origin Title   111 / 423 Problem A LightOJ 1370 Bi-shoe and Phi-shoe   21 / 74 Problem B ...

随机推荐

  1. Flask 使用Jinja2模板引擎

    Jinja2,由Flask框架的创作者开发,是一款功能丰富的模板引擎,以其完整的Unicode支持.灵活性.高效性和安全性而备受推崇.最初受Django模板引擎启发,Jinja2为Flask提供了强大 ...

  2. Linux删除‘-’开头的文件

    版权声明:原创作品,谢绝转载!否则将追究法律责任. ----- 作者:kirin 先看两个特殊文件(以--开头) [root@kirin ~]# ll total 0 -rw-r--r-- 1 roo ...

  3. VLOOKUP函数10种经典用法

    VLOOKUP函数是Excel中非常常用的函数之一,可以用于在一个区域或表格中查找某个值,并返回该值所在行的另一个指定列中的数值.以下是VLOOKUP函数的10种经典用法: 基本的VLOOKUP用法: ...

  4. IIS安装与配置

    一.环境介绍 Windows Server 2019 64位 标准版 二.IIS安装 2.1.打开服务器管理器,单击添加角色和功能 在Windows Server 2019 服务器管理中,点击角色和功 ...

  5. SpringBoot实战项目:蚂蚁爱购(从零开发)

    ​ 简介 这是从零开发的SpringBoot实战项目,名字叫蚂蚁爱购. 从零开发项目,视频加文档,十天彻底掌握开发SpringBoot项目. 教程路线是:搭建环境=> 安装软件=> 创建项 ...

  6. idea用不了 idea.bat文件闪退

    由于idea的智能,在破解之后会留下一些问题,根据网上搜出来的解决办法. 1.C:\Users\dell\AppData\Roaming\JetBrains\IntelliJIdea2022.2 在这 ...

  7. Mybatis-Flex之QueryWrapper

    1.完整DQL语句 /** * 使用QueryWrapper构建超复杂SQL语句 */ @Test public void testQueryWrapper1() { QueryWrapper wra ...

  8. Spring中Bean的加载方式~

    1.方式一:基于spring.xml方式配置Bean user import lombok.Data; /** * @author : ly */ @Data public class User { ...

  9. 国产 Web 组态软件在玻璃生产线中的应用

    ​  概述 随着工厂信息化.数字化发展,智慧生产车间成为必然发展趋势,通过智能硬件.物联网.大数据等智慧化技术与手段,提高车间生产设备.工艺设备的智能执行能力,从而提升整个车间乃至工厂的智能化.网络化 ...

  10. 开源MES/免费MES/开源mes 生产管理流程

    开源MES/免费MES/开源MES生产流程管理 一.什么是MES生产管理流程 生产管理系统(又称制造执行系统)是一种集成了计划.生产.质量控制.库存管理和材料申请等生产流程的管理系统.工厂生产管理流程 ...