FATE
Problem Description
最近xhd正在玩一款叫做FATE的游戏,为了得到极品装备,xhd在不停的杀怪做任务。久而久之xhd开始对杀怪产生的厌恶感,但又不得不通过杀怪来升完这最后一级。现在的问题是,xhd升掉最后一级还需n的经验值,xhd还留有m的忍耐度,每杀一个怪xhd会得到相应的经验,并减掉相应的忍耐度。当忍耐度降到0或者0以下时,xhd就不会玩这游戏。xhd还说了他最多只杀s只怪。请问他能升掉这最后一级吗?
Input
输入数据有多组,对于每组数据第一行输入n,m,k,s(0 < n,m,k,s < 100)四个正整数。分别表示还需的经验值,保留的忍耐度,怪的种数和最多的杀怪数。接下来输入k行数据。每行数据输入两个正整数a,b(0 < a,b < 20);分别表示杀掉一只这种怪xhd会得到的经验值和会减掉的忍耐度。(每种怪都有无数个)
Output
输出升完这级还能保留的最大忍耐度,如果无法升完这级输出-1。
Sample Input
10 10 1 10
1 1
10 10 1 9
1 1
9 10 2 10
1 1
2 2
Sample Output
0
-1
1
思路:典型的dp题,只要注意好状态转移方程:dp[i][na] = max(dp[i][na], dp[i - RN[j]][na - 1] + JY[j])。
下面给出AC代码:
#include<iostream>
#include<algorithm>
int dp[500][500];
int JY[300], RN[300];
using namespace std;
int main()
{
int n, m, k, s;
while (cin >> n >> m >> k >> s)
{
;
int flag = 0;
memset(dp, 0, sizeof(dp));
memset(JY, 0, sizeof(JY));
memset(RN, 0, sizeof(RN));
for (int i = 1; i <= k; i++)
{
cin >> JY[i] >> RN[i];
}
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= k; j++)
for (int na = 1; na <= s; na++)
{
if (RN[j] <= i)
dp[i][na] = max(dp[i][na], dp[i - RN[j]][na - 1] + JY[j]);
}
if (dp[i][s] >= n)
{
flag = i;
break;
}
}
if (flag==0) cout << "-1" << endl;
else cout << m - flag << endl;
}
}
HOW TO TYPE
Problem Description
Pirates have finished developing the typing software. He called Cathy to test his typing software. She is good at thinking. After testing for several days, she finds that if she types a string by some ways, she will type the key at least. But she has a bad habit that if the caps lock is on, she must turn off it, after she finishes typing. Now she wants to know the smallest times of typing the key to finish typing a string.
Input
The first line is an integer t (t<=100), which is the number of test case in the input file. For each test case, there is only one string which consists of lowercase letter and upper case letter. The length of the string is at most 100.
Output
For each test case, you must output the smallest times of typing the key to finish typing this string.
Sample Input
3
Pirates
HDUacm
HDUACM
Sample Output
8
8
8
Hint
The string “Pirates”, can type this way, Shift, p, i, r, a, t, e, s, the answer is 8.
The string “HDUacm”, can type this way, Caps lock, h, d, u, Caps lock, a, c, m, the answer is 8
The string "HDUACM", can type this way Caps lock h, d, u, a, c, m, Caps lock, the answer is 8
思路:
动态规划问题,创建dp[2][105]分别代表小写状态和大写状态。
输入用a+1,便于dp;
对于dp[0][i],dp[1][i](大写),因为Cathy每次用完大写都会关掉,前一状态不管大小写都是dp[0][i-1]+2或者dp[1][i-1]+2;
小写时,前一状态分别是dp[0][i]对应dp[0][i-1]+1或者dp[1][i-1]+2,dp[1][i]对应dp[0][i-1]+2或者dp[1][i-1]+2;
下面给出AC代码:
#include<iostream>
#include<algorithm>
char a[105], p[1010],e[1010];
int dp[2][105];
using namespace std;
int main()
{
int t;
cin >> t;
while (t--)
{
memset(dp, 0, sizeof(dp));
dp[0][0] = 0, dp[1][0] = 1;
cin >> (a + 1);
int len = strlen(a + 1);
for (int i = 1; a[i]; i++)
{
if (a[i] >= 'A'&&a[i] <= 'Z')
{
dp[0][i] = min(dp[0][i - 1] + 2, dp[1][i - 1] + 2);
dp[1][i] = min(dp[0][i - 1] + 2, dp[1][i - 1] + 1);
}
else if (a[i] >= 'a'&&a[i] <= 'z')
{
dp[0][i] = min(dp[0][i - 1] + 1, dp[1][i - 1] + 2);
dp[1][i] = min(dp[0][i - 1] + 2, dp[1][i - 1] + 2);
}
}
cout << min(dp[0][len], dp[1][len] + 1) << endl;
}
}