简单DP (Preparing for Xtreme 12.0)

   当水题遇上了map大坑

    晚上写一个dp,弄了半天样例一直不过,对着队友的代码一行行看,发现跟自己逻辑完全一样啊。。。

    然后就逐行输出比对,发现预处理出了问题,把map插入新值的地方改了下,果然就好了。。。

    折腾半晚上,不吐不快。

    以前使用STL的map时,一直把它当作一种高级数组,很少使用insert来插入键值对,都是直接用下标索引直接插入新值。而在map中查找key时,我也一般直接采取判断mp[key]是否为0。

    而这题这样用也没多大问题,就怪我太作了,把tot默认设置为-1,方便++tot后从0开始计数。。。

    但是插入跟第一个相同的key时,由于ID[key]==0,就把ID[key]的值更新了。。。

    调试半天都没发现这样的bug啊T_T T_T T_T

    直接上AC代码:

#include<iostream>
#include<vector>
#include<cstring>
#include<sstream>
#include<algorithm>
#include<map>
using namespace std;
const int INF = 0x3f3f3f3f;
int b, tot;
map<string, int> ID;
struct book{
    int id;
    int cost;
}books[110];

int dp[1<<22];

int main()
{
    int cost;
    while(cin>>cost) {
        books[b].cost = cost;

        string line, book;
        getline(cin, line);
        stringstream ss(line);
        while(ss>>book) {
            // if(!ID.count(book)) ID.insert(make_pair(book, ++tot));
            // if(ID.find(book)==ID.end()) ID.insert(make_pair(book, ++tot));

            // map里没有键book,则插入
            if(!ID[book]) ID[book] = ++tot;
            books[b].id |= 1<<(ID[book]-1);
        }
        b++;
    }

    int S = 1<<tot;
    dp[0] = 0;
    for(int i=1;i<S;i++) dp[i] = INF;
    for(int i=0;i<S;i++) {
        for(int j=0;j<b;j++) {
            dp[i|books[j].id] = min(dp[i|books[j].id], dp[i]+books[j].cost);
        }
    }
    cout<<dp[S-1]<<endl;
    return 0;
}

    最后关于map的使用,还是推荐注释部分的写法。

    这篇博客讲了这两种插入的效率问题,我想区别不是太大,直接用ID[book]=++tot也是可以的。

    在以后的使用中还是要尽量避免直接使用下标访问,应该如果你要访问的key不存在的话,会默认插入新的值,size也会增加。

 

     map的查找操作使用总结如下

  1. 在map中,由key查找value时,首先要判断map中是否包含key。

  2. 如果不检查,直接返回map[key],可能会出现意想不到的行为。如果map包含key,没有问题,如果map不包含key,使用下标有一个危险的副作用,会在map中插入一个key的元素,value会取默认值0。

  3. map提供了两种方式,查看是否包含key,m.count(key),m.find(key)。

  4. m.count(key):由于map不包含重复的key,因此m.count(key)取值为0,或者1,表示是否包含。

  5. m.find(key):返回迭代器,判断是否存在。

猜你喜欢

转载自www.cnblogs.com/izcat/p/10680808.html