CSDN第二十九期周赛

  1. 订班服 小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;
}

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安特尼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值