订班服 小A班级订班服了! 可是小A是个小糊涂鬼,整错了好多人的衣服的大小。 小A只能自己掏钱包来补钱了。 小A想知道自 己至少需要买多少件衣服。
用unordered_map来将字符串映射成数字,用数组记录件数,最后查询相差件数。
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <cmath>
#include <unordered_map>
using namespace std ;
int n , res ;
int a[110] , b[110] ;
int cnt = 1 ;
int main() {
cin >> n ;
unordered_map<string,int> mp ;
for(int i = 0 ; i < n ; i ++)
{
string s ;
cin >> s ;
if(!mp[s]) mp[s] = cnt ++ ;
a[mp[s]] ++ ;
}
for(int i = 0 ; i < n ; i ++)
{
string s ;
cin >> s ;
if(!mp[s]) mp[s] = cnt ++ ;
b[mp[s]] ++ ;
}
for(int i = 1 ; i < cnt ; i ++)
res += abs(a[i] - b[i]) ;
cout << res / 2 << endl ;
return 0;
}
2、争抢糖豆
抓糖豆,小Q与小K都喜欢吃糖豆。 但是糖豆分两种,超甜糖豆和普通糖豆。 现在有w个超甜糖豆和b个普通糖豆。 小Q和 小K开始吃糖豆,他们决定谁先吃到超甜糖豆谁就获胜。 小K每次吃的时候会捏碎一颗糖豆。 小Q先吃,小Q想知道自己获 胜的概率。 如果两个人都吃不到超甜糖豆小K获胜。
典型的DP问题,用数组f[i][j]来记录i个超级糖豆,j个普通糖豆的数量,理清状态数组之间的转换关系,这道问题就可以解决了。
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std ;
int w , b ;
double f[1010][1010] ;
int main() {
cin >> w >> b ;
for(int i = 1 ; i <= w ; i ++) f[i][0] = 1 ;
for(int i = 1 ; i <= w ; i ++)
for(int j = 1 ; j <= b ; j ++)
{
f[i][j] = (double) i * 1.0 / (i + j) ;
if(j >= 2) f[i][j] += (double) j / (i + j) * (j - 1) / (i + j - 1) * i / (i + j - 2) * f[i - 1][j - 2] ;
if(j >= 3) f[i][j] += (double) j / (i + j) * (j - 1) / (i + j - 1) * (j - 2) / (i + j - 2) * f[i][j - 3] ;
}
printf("%.9lf\n",f[w][b]) ;
return 0;
}
3.走楼梯
现在有一截楼梯,根据你的腿长,你一次能走 1 级或 2 级楼梯,已知你要走 n 级楼梯才能走到你的目的楼层,请实现一 个方法,计算你走到目的楼层的方案数。
这也是一道DP问题,状态转换比上题也要简单许多,f[i] = f[i - 1] + f[i - 2] ;
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std ;
typedef long long LL ;
int n ;
LL f[55] ;
int main() {
cin >> n ;
f[0] = 1 ;
f[1] = 1 ;
for(int i = 2 ; i <= n ; i ++)
f[i] = f[i - 1] + f[i - 2] ;
cout << f[n] << endl ;
return 0;
}
4、打家劫舍 一个小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通 的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个房屋存放金额的非负整数 数组,计算不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额
呃,这也是一道DP问题,这次周赛考了三道DP,不过第二题难度应该是最高的了。
这道题不能连续偷两个相邻的房屋,所以状态转移方程是 1.偷这家,就由 f[i - 2] + w[i]
2.不偷这家 由 f[i - 1]转移来即可。
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std ;
typedef long long LL ;
const int N = 110 ;
int n ;
LL f[N] , a[N] ;
int main() {
cin >> n ;
for(int i = 1 ; i <= n ; i ++) cin >> a[i] ;
f[1] = a[1] ;
for(int i = 2 ; i <= n ; i ++) f[i] = max(f[i - 2] + a[i] , f[i - 1]) ;
cout << f[n] << endl ;
return 0;
}