4.15 每周作业 —— 简单DP
免费馅饼
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 102 Accepted Submission(s) : 35
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description

为了使问题简化,假设在接下来的一段时间里,馅饼都掉落在0-10这11个位置。开始时gameboy站在5这个位置,因此在第一秒,他只能接到4,5,6这三个位置中其中一个位置上的馅饼。问gameboy最多可能接到多少个馅饼?(假设他的背包可以容纳无穷多个馅饼)
Input
Output
提示:本题的输入数据量比较大,建议用scanf读入,用cin可能会超时。
Sample Input
6
5 1
4 1
6 1
7 2
7 2
8 3
0
Sample Output
4 思路: 简单DP,按照DP的思考步骤。 一.找到最优子问题
那么我们的问题就是 “左 中 右”的选择 二.找到决策,也就是会影响到结果的因素
那么这个问题会影响到结果的就是 时间和地点 三.提出状态
由第二点可以知道,影响到结果的有两个因素,所以状态应该是二维的
DP[i][j]==在 i秒 的时候 在 j点 的馅饼数 四.提出状态转移方程
考虑到边界问题,如果我们在第 0 点 或者 第 10 点,那我们的选择就只有 “在原地”或者 “旁边的一个”,这样就只有两个选择,所以需要特判一下
if(j<=){
j=;
dp[i][j]=max(dp[i-][j],dp[i-][j+])+cake[i][j];
}
else if(j==){
dp[i][j]=max(dp[i-][j],dp[i-][j-])+cake[i][j];
}
else{
dp[i][j]=max_judge(dp[i-][j-],dp[i-][j],dp[i-][j+])+cake[i][j];//比较一下第i秒的j号位置,是上一秒的j的左边,还是上一秒的j的右边,还是上一秒的j最多
}
其实我们可以看到,我们每次要考虑到的只有上一秒的情况,所以其实可以用滚动数组来节省空间,不过我懒得写了,不会的话参考01背包的滚动数组情况。
下面给出麻烦代码
//#pragma comment(linker,"/STACK:1024000000,1024000000")
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<set>
#include<map>
using namespace std; int n;
int T,x;
int loc;
int Max;
int sum_time;
int cake[][];
int dp[][]; int max_judge(int a,int b,int c)
{
int ans;
ans=a>b?a:b;
ans=ans>c?ans:c;
return ans;
} int main()
{
while(cin>>n && n)
{
loc=;
Max=;
sum_time=;
memset(dp,,sizeof(dp));
memset(cake,,sizeof(cake));
for(int i=;i<=n;i++){
scanf("%d%d",&x,&T);
sum_time=max(T,sum_time);
cake[T][x]++;
} for(int i=;i<=sum_time;i++){
for(int j=loc-i;j<= && j<=loc+i;j++){
if(j<=){
j=;
dp[i][j]=max(dp[i-][j],dp[i-][j+])+cake[i][j];
}
else if(j==){
dp[i][j]=max(dp[i-][j],dp[i-][j-])+cake[i][j];
}
else{
dp[i][j]=max_judge(dp[i-][j-],dp[i-][j],dp[i-][j+])+cake[i][j];
}
} }
for(int i=;i<=;i++){
Max=max(dp[sum_time][i],Max);
}
cout<<Max<<endl;
}
return ;
}
搬寝室
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 63 Accepted Submission(s) : 23
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
Input
Output
Sample Input
2 1
1 3
Sample Output
4
Author
Source
思路:这题一开始感觉是简单排序,然后就WA了,后面想想不行 比如 1 99 100 这样的数据,简单排序选择的话 就会选择1 和99 ,但实际上是 99 和 100.
还是得靠DP来解决。
正式开始
首先,我们先sort排序下。 这样,我们知道,两个数的差最小的话,肯定是排序后的左边一个和右边一个,这样我们的问题就变成了选左边或者右边。
下面按照DP的简单思路:
一.找出最小子问题
我们的问题就是选出相差值最小的一对,那么我们面对的问题就 我们要拿的这一对中 包不包含现在面对的这个 东西
二.找到决策,也就是影响到结果的因素
那么我们可以知道,影响到问题的决策 也就是 物品 和 对数
三.提出状态
由二我们可以知道影响到问题的决策有两个 也就是 状态也就是 二维的
DP[i][j]==在面对第 i 个 物品时,拿了 j 对 物品的疲劳值
四.提出转移方程
dp[i][j] = Min_(dp[i - ][j - ] +sum(wei[i],wei[i-]),dp[i - ][j]);
//比较下 是拿 这一个加前一个 这一对 加上前面的对数 的疲劳值 和 不拿这一个 的 对数 的疲劳值
下面给出AC程序:
可能还是有人比较模糊,那就再解释下。
我们从最小的状态开始,也就是
比如只有 a b两件,那么我们只能拿这两个
但是如果有 a b c 三件,首先我们知道 c-a 肯定是大于 c-b的,所以不需要考虑
所以我们要考虑的是要不要拿c,如果拿c的话,那么我们肯定是要拿b的,如果不拿c的话,那么我们就是拿a 和 b了
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std; #define M 2005
typedef int ll; ll n, k;
ll limit_i;
ll limit_k;
ll wei[M];
ll dp[M][M]; void init()
{
memset(dp, 0x3f3f3f3f, sizeof(dp));
for (int i = ; i <= n; i++) {
dp[i][] = dp[][i] = ;
}
} ll Min_(ll a, ll b)
{
return a < b ? a : b;
} ll sum(ll a, ll b)
{
return (a - b)*(a - b);
} int main()
{
while (cin>>n>>k)
{
init();
for (int i = ; i <= n; i++) {
scanf("%d", &wei[i]);
}
sort(wei + , wei + n + ); for (int i = ; i <= n; i++) {
limit_i = (i >>);
for (int j = ; j <= limit_i && j <= k; j++) {
dp[i][j] = Min_(dp[i - ][j - ] +sum(wei[i],wei[i-]),dp[i - ][j]);
}
}
cout << dp[n][k] << endl;
}
return ;
}
Humble Numbers
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 12 Accepted Submission(s) : 9
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
Write a program to find and print the nth element in this sequence
Input
Output
Sample Input
1
2
3
4
11
12
13
21
22
23
100
1000
5842
0
Sample Output
The 1st humble number is 1.
The 2nd humble number is 2.
The 3rd humble number is 3.
The 4th humble number is 4.
The 11th humble number is 12.
The 12th humble number is 14.
The 13th humble number is 15.
The 21st humble number is 28.
The 22nd humble number is 30.
The 23rd humble number is 32.
The 100th humble number is 450.
The 1000th humble number is 385875.
The 5842nd humble number is 2000000000.
Source
//#pragma comment(linker,"/STACK:1024000000,1024000000")
#include<iostream>
#include<algorithm>
#include<iterator>
#include<cstdio>
#include<cstring>
#include<string>
#include<stack>
#include<list>
#include<set>
#include<deque>
#include<utility>
#include<ctime>
using namespace std; typedef long long ll; ll t;
ll temp;
ll n[] = { ,,, };
ll ans[];
set<ll>num;
string str[]; void init()
{
num.insert(), num.insert();
register set<ll>::iterator iter = num.begin();
for (int i = ; i <= ; i++) {
iter++;
for (int j = ; j < ; j++) {
temp = (*iter)*n[j];
num.insert(temp);
}
}
iter = num.begin();
for (int i = ; i <= ; i++) {
ans[i] = *iter;
iter++;
}
str[] = "th", str[] = "st", str[] = "nd", str[] = "rd";
for (int i = ; i <= ; i++) {
str[i] = "th";
}
} int main()
{
init();
while (cin>>t && t)
{
cout << "The " << t;
if (t% == || t % == || t % == ) {
cout << str[];
}
else {
cout << str[t % ];
}
cout << " humble number is " << ans[t] << '.' << endl;
}
return ;
}
Super Jumping! Jumping! Jumping!
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 44 Accepted Submission(s) : 27
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
The game can be played by two or more than two players. It consists of a chessboard(棋盘)and some chessmen(棋子), and all chessmen are marked by a positive integer or “start” or “end”. The player starts from start-point and must jumps into end-point finally. In the course of jumping, the player will visit the chessmen in the path, but everyone must jumps from one chessman to another absolutely bigger (you can assume start-point is a minimum and end-point is a maximum.). And all players cannot go backwards. One jumping can go from a chessman to next, also can go across many chessmen, and even you can straightly get to end-point from start-point. Of course you get zero point in this situation. A player is a winner if and only if he can get a bigger score according to his jumping solution. Note that your score comes from the sum of value on the chessmen in you jumping path.
Your task is to output the maximum value according to the given chessmen list.
Input
N value_1 value_2 …value_N
It is guarantied that N is not more than 1000 and all value_i are in the range of 32-int.
A test case starting with 0 terminates the input and this test case is not to be processed.
Output
Sample Input
3 1 3 2
4 1 2 3 4
4 3 3 2 1
0
Sample Output
4
10
3
Author
if (num[j] < num[i]) {
dp[i] = max(dp[i], dp[j] + num[i]);
}//比较一下,如果以i点为结尾的话,会不会更大
下面给出AC方程:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<stack>
#include<list>
#include<deque>
#include<utility>
using namespace std; #define M 1005 int n;
int ans;
int dp[M];
int num[M]; void init()
{
ans = ;
for (int i = ; i <= n; i++) {
dp[i] = num[i];
}
} int main()
{
while (cin>>n && n)
{
for (int i = ; i <= n; i++) {
cin >> num[i];
}
init();
for (int i = ; i <= n; i++) {
for (int j = ; j <= i; j++) {
if (num[j] < num[i]) {
dp[i] = max(dp[i], dp[j] + num[i]);
}
}
ans = max(ans, dp[i]);
}
cout << ans << endl;
} return ;
}
龟兔赛跑
Time Limit : 1000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 18 Accepted Submission(s) : 8
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
最近正值HDU举办50周年校庆,社会各大名流齐聚下沙,兔子也趁此机会向乌龟发起挑战。虽然乌龟深知获胜希望不大,不过迫于舆论压力,只能接受挑战。
比赛是设在一条笔直的道路上,长度为L米,规则很简单,谁先到达终点谁就算获胜。
无奈乌龟自从上次获胜以后,成了名龟,被一些八卦杂志称为“动物界的刘翔”,广告不断,手头也有了不少积蓄。为了能够再赢兔子,乌龟不惜花下血本买了最先进的武器——“"小飞鸽"牌电动车。这辆车在有电的情况下能够以VT1 m/s的速度“飞驰”,可惜电池容量有限,每次充满电最多只能行驶C米的距离,以后就只能用脚来蹬了,乌龟用脚蹬时的速度为VT2 m/s。更过分的是,乌龟竟然在跑道上修建了很多很多(N个)的供电站,供自己给电动车充电。其中,每次充电需要花费T秒钟的时间。当然,乌龟经过一个充电站的时候可以选择去或不去充电。
比赛马上开始了,兔子和带着充满电的电动车的乌龟并列站在起跑线上。你的任务就是写个程序,判断乌龟用最佳的方案进军时,能不能赢了一直以恒定速度奔跑的兔子。
Input
第一行是一个整数L代表跑道的总长度
第二行包含三个整数N,C,T,分别表示充电站的个数,电动车冲满电以后能行驶的距离以及每次充电所需要的时间
第三行也是三个整数VR,VT1,VT2,分别表示兔子跑步的速度,乌龟开电动车的速度,乌龟脚蹬电动车的速度
第四行包含了N(N<=100)个整数p1,p2...pn,分别表示各个充电站离跑道起点的距离,其中0<p1<p2<...<pn<L
其中每个数都在32位整型范围之内。
Output
题目数据保证不会出现乌龟和兔子同时到达的情况。
Sample Input
100
3 20 5
5 8 2
10 40 60
100
3 60 5
5 8 2
10 40 60
Sample Output
Good job,rabbit!
What a pity rabbit!
Author
Source
dp[i] = min(dp[i], dp[j] + sum(i, j));//sum计算的是从j到i花费的时间
下面是AC方程:
//#pragma comment(linker,"/STACK:1024000000,1024000000")
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<stack>
#include<list>
#include<deque>
#include<utility>
using namespace std; #define M 105
#define inf 0x3f3f3f3f
typedef double i_d; int L;
i_d r_time;
int st, ed;
i_d N, C, T;
i_d VR, VT1, VT2;
i_d dp[];
int num[]; void init()
{
r_time = L / VR;
ed = , st = N + ;
num[ed] = , num[st] = L;
for (int i = ; i <= st; i++) {
dp[i] = inf;
}
dp[] = ;
} void get_data()
{
cin >> N >> C >> T;
cin >> VR >> VT1 >> VT2;
for (int i = ; i <= N; i++) {
cin >> num[i];
}
} i_d sum(int a, int b)
{
i_d dis, time;
dis = num[a] - num[b];
if (dis <= C) {
time=dis / VT1;
}
else {
time = C / VT1 + (dis - C) / VT2;
}
return b == ? time : time + T;//记住如果j站为0的话那么就是起点,起点不需要充电,也就不需要花费T时间
} int main()
{
while (cin>>L)
{
get_data();
init();
for (int i = ; i <= st; i++) {
for (int j = ; j < i; j++) {
dp[i] = min(dp[i], dp[j] + sum(i, j));
}
}
if (r_time < dp[st]) {
cout << "Good job,rabbit!" << endl;
}
else {
cout << "What a pity rabbit!" << endl;
}
}
return ;
}
FatMouse's Speed
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 12 Accepted Submission(s) : 5
Special Judge
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
Input
The data for a particular mouse will consist of a pair of integers: the first representing its size in grams and the second representing its speed in centimeters per second. Both integers are between 1 and 10000. The data in each test case will contain information for at most 1000 mice.
Two mice may have the same weight, the same speed, or even the same weight and speed.
Output
W[m[1]] < W[m[2]] < ... < W[m[n]]
and
S[m[1]] > S[m[2]] > ... > S[m[n]]
In order for the answer to be correct, n should be as large as possible.
All inequalities are strict: weights must be strictly increasing, and speeds must be strictly decreasing. There may be many correct outputs for a given input, your program only needs to find one.
Sample Input
6008 1300
6000 2100
500 2000
1000 4000
1100 3000
6000 2000
8000 1400
6000 1200
2000 1900
Sample Output
4
4
5
9
7
Source
//#pragma comment(linker,"/STACK:1024000000,1024000000")
#include<iostream>
#include<algorithm>
#include<iterator>
#include<cstdio>
#include<cstring>
#include<string>
#include<stack>
#include<list>
#include<set>
#include<queue>
#include<deque>
#include<utility>
#include<ctime>
using namespace std; #define M 1005
#define inf 0x3f3f3f3f struct Data
{
int id;
int wei;
int speed;
bool operator<(Data &x){
return wei < x.wei;
}
}Mouse[M];
int dp[M];
int ans[M];
int n, len, tail;
int id, wei, speed; void get_data()
{
id = ;
while (cin>>wei>>speed)
{
//if (wei == 0) { break; }
Mouse[id].id = id;
Mouse[id].wei = wei;
Mouse[id++].speed = speed;
}
Mouse[].wei = inf, Mouse[].speed = -inf;
n = id - ;
} void dfs(int T)
{
if (!T) {
return;
}
dfs(ans[T]);
cout << Mouse[T].id << endl;
} int main()
{
get_data();
sort(Mouse + , Mouse + n + );
for (int i = ; i <= n; i++) {
dp[i] = ;
for (int j = ; j < i; j++) {
if (Mouse[i].wei > Mouse[j].wei && Mouse[i].speed < Mouse[j].speed && dp[i] < dp[j] + ) {
dp[i] = dp[j] + ;
ans[i] = j;
}
}
if (len < dp[i]) {
len = dp[i];
tail = i;
}
}
cout << len << endl;
dfs(tail);
return ;
}
Common Subsequence
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 12 Accepted Submission(s) : 6
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
The program input is from a text file. Each data set in the file contains two strings representing the given sequences. The sequences are separated by any number of white spaces. The input data are correct. For each set of data the program prints on the standard output the length of the maximum-length common subsequence from the beginning of a separate line.
Sample Input
abcfbc abfcab
programming contest
abcd mnp
Sample Output
4
2
0
Source
//#pragma comment(linker,"/STACK:1024000000,1024000000")
#include<iostream>
#include<algorithm>
#include<iterator>
#include<cstdio>
#include<cstring>
#include<string>
#include<stack>
#include<list>
#include<set>
#include<deque>
#include<utility>
#include<ctime>
using namespace std; #define M 1005 int a_len;
int b_len;
int dp[M][M];
char a[M], b[M]; void init()
{
a_len = strlen(a + ), b_len = strlen(b + );
for (int i = ; i <= a_len; i++) {
for (int j = ; j <= b_len; j++) {
dp[i][j] = ;
}
}
} int main()
{
while (scanf("%s%s",a+,b+)!=EOF)
{
init();
for (int i = ; i <= a_len; i++) {
for (int j = ; j <= b_len; j++) {
if (a[i] == b[j]) {
dp[i][j] = dp[i - ][j - ] + ;
}
else {
dp[i][j] = max(dp[i - ][j], dp[i][j-]);
}
}
}
cout << dp[a_len][b_len] << endl;
}
return ;
}
4.15 每周作业 —— 简单DP的更多相关文章
- 软工网络15团队作业4——Alpha阶段敏捷冲刺2.0
软工网络15团队作业4--Alpha阶段敏捷冲刺2.0 1.提供当天站立式会议照片一张. 2.每个人的工作 成员 昨天已完成 今天计划完成 郭炜埕 熟悉微信web开发者工具 完成新建话题界面的设计 郑 ...
- 软工网络15团队作业4——Alpha阶段敏捷冲刺3.0
软工网络15团队作业4--Alpha阶段敏捷冲刺3.0 1.每天举行站立式会议,提供当天站立式会议照片一张. 2.项目每个成员的昨天进展.存在问题.今天安排. 成员 昨天已完成 今天计划完成 郭炜埕 ...
- 软工网络15团队作业4——Alpha阶段敏捷冲刺8.0
软工网络15团队作业4--Alpha阶段敏捷冲刺8.0 1.每天举行站立式会议,提供当天站立式会议照片一张. 2.项目每个成员的昨天进展.存在问题.今天安排. 2.1 任务完成安排: 成员 昨日已完成 ...
- 面向对象OO第15次作业总结
面向对象OO第15次作业总结 1.论述测试与正确性论证的效果差异,比较其优缺点测试通过大量测试数据来覆盖测试代码,比较直观,优点在于知道测的是啥,特别直观,缺点在于很难覆盖所有情况.正确性论证从逻辑关 ...
- 简单 dp
1.摆花问题 题目描述小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共m盆.通过调查顾客的喜好,小明列出了顾客最喜欢的n种花,从1到n标号.为了在门口展出更多种花,规定第i种花不能超过a ...
- HDU 5375 Gray code (简单dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5375 题面: Gray code Time Limit: 2000/1000 MS (Java/Oth ...
- HDU 1087 简单dp,求递增子序列使和最大
Super Jumping! Jumping! Jumping! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 ...
- Codeforces Round #260 (Div. 1) A. Boredom (简单dp)
题目链接:http://codeforces.com/problemset/problem/455/A 给你n个数,要是其中取一个大小为x的数,那x+1和x-1都不能取了,问你最后取完最大的和是多少. ...
- codeforces Gym 100500H A. Potion of Immortality 简单DP
Problem H. ICPC QuestTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100500/a ...
随机推荐
- jquery实现搜索框从中间向两边扩展(左右放大)
显示效果: 隐藏效果: 前端核心代码如下: <div class="search-icon col-md-2 col-sm-2 col-xs-4 col-md-offset-5 col ...
- tensorflow--建立一个简单的小网络
In [19]: import tensorflow as tf import numpy as np # #简单的数据形网络 # #定义输入参数 # X=tf.constant( ...
- 用AD 输出BOM时提示failed to open excel template
解决办法: 去掉这个√!
- EUI库 - 9 - 数据集合 - 列表
List 和DataGroup的区别 1 选中一项 会触发 eui.ItemEvent.ITEM_TAP 事件, 2 有选中项的概念,可以设置 List 里的默认选中项 selectedIn ...
- webservice 的简单实现
1.什么是webservice: 服务端整出一些资源让客户端访问(获取数据) 一个跨语言.跨平台的规范2.作用:跨平台调用.跨语言调用.远程调用 3.什么时候使用webservice: 1.新旧系统之 ...
- hdfs 删除和新增节点
最近发现hdfs的一个问题,每当集群开启的时候,有一个节点上的可用空间就一直在减少,并且速度很快,发现是data目录下的dncp_block_verification.log.curr文件在一直变大, ...
- SQL约束攻击
本文转载自https://blog.csdn.net/kkr3584/article/details/69223010 目前值得高兴的是,开发者在建立网站时,已经开始关注安全问题了--几乎每个开发者都 ...
- SAP_FICO常用事务代码
1.会计科目维护: FS00:总账科目主记录维护 FSP0:科目表中总账科目主记录维护 FSS0:公司代码中总账科目主记录维护 2.会计凭证创建 FB01:创建凭证 F-02:总账凭证创建(在FB01 ...
- POJ - 1742 Coins(dp---多重背包)
题意:给定n种硬币的价值和数量,问能组成1~m中多少种面值. 分析: 1.dp[j]表示当前用了前i种硬币的情况下,可以组成面值j. 2.eg: 3 10 1 3 4 2 3 1 (1)使用第1种硬币 ...
- 进度2_家庭记账本App
今天在昨天的基础上,相继完成了三个页面的布局和显示情况: 新增加的xml文件如下: activity_add.xml: <?xml version="1.0" encodin ...