- 问题来源
 - 问题简介
给你一系列字符串stickers,问要在stickers中找多少个字符串(可重复使用)才能找到足够的字符(不可重复使用)拼出target字符串。若无法拼出则返回-1。
 
解题思路
如果为target的每一位设置已填充和未填充的状态的话,则总共有 2 ^ length-of-target种状态,且,int值较大的状态一定是有int值较小的状态而来的。
| 时间复杂度 | 空间复杂度 | 
|---|---|
| O(未知) | O(未知) | 
Code
class Solution {
public:
    int minStickers(vector<string>& stickers, string target) {
        // 令int值的每一位代表target在相应位置是否已被填充,则总共有1 << N个状态
        int N = target.length(), len_dp = 1 << N;
        // 到达每个状态的步数为-1
        vector<int> dp(len_dp, -1);
        // 初始状态为 0,步数为0
        dp[0] = 0;
        // 每个状态都是由前面的状态而来
        for (int i = 0; i < len_dp; i++) {
            // 遍历每个状态,并转移状态
            if (dp[i] == -1) {
                continue;
            }
            for (auto str : stickers) {
                int nowState = i;
                for (char letter : str) {
                    for (int j = 0; j < N; j++) {
                        if (nowState & (1 << j)) {
                            // 该位已被填充
                            continue;
                        }
                        if (target[j] == letter) {
                            // 填充该位
                            nowState |= (1 << j);
                            break;
                        }
                    }
                }
                // 状态已转移
                if (dp[nowState] == -1 || dp[nowState] > dp[i] + 1) {
                    dp[nowState] = dp[i] + 1;
                }
            }
        }
        return dp[len_dp-1];
    }
};
