2023-3-30刷题情况

统计字典序元音字符串的数目

思路

可以缩短问题的规模,将其转换为相同类型的子问题。可以使用动态规划。

  • 状态表示: dp[i][k] 为第 i 个数以第k个字母的字符结尾的元音字符串的数目。
  • 状态转移方程: dp[i][k] = max ⁡ j ∈ [ 0 , k ] ( d p [ i − 1 ] [ j ] ) + 1 \max_{j \in [0,k] }(dp[i-1][j]) + 1 maxj[0,k](dp[i1][j])+1
  • 边界条件 : dp[i][0~k] = 1, ( i ∈ n ) (i \in n) (in)

代码实现

class Solution {
    public int countVowelStrings(int n) {
        int[] dp = new int[5];
        for(int i = 0; i < 5; i++) dp[i] = 1;
        int a, e, i, o, u;
        for(int k = 1; k < n; k++){
            a = dp[0];
            e = dp[1];
            i = dp[2];
            o = dp[3];
            u = dp[4];
            dp[0] = a;
            dp[1] = a + e;
            dp[2] = a + e + i;
            dp[3] = a + e + i + o;
            dp[4] = a + e + i + o + u;
        }
        return Arrays.stream(dp).sum();
    }
}

糖果

思路

状压dp,数据范围很小,可直接用二进制的形式表示当前这个数存在或者不存在。
*状态转移方程:dp[j | a[i]] = max(dp[j | a[i]], dp[j] + 1)

代码实现

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(), m = sc.nextInt(), k = sc.nextInt();
        int[] arr = new int[n + 1];
        boolean[] vis = new boolean[m];
        int tmp;
        for(int i = 1; i <= n; i++){
            for(int j = 0; j < k; j++){
                tmp = sc.nextInt() - 1;
                vis[tmp] = true;
                arr[i] |= 1 << tmp; 
            }
        }
        for(int i = 0; i < m; i++){
            if(!vis[i]){
                System.out.println("-1");
                return;
            } 
        }
        
        int[] f = new int[1 << m];
        Arrays.fill(f, (int)1e9+7);
        f[0] = 0;
        for(int i = 1; i <= n; i++){
            for(int j = (1<<m) -1; j >= 0; j--){
                f[j | arr[i]] = Math.min(f[j | arr[i]], f[j] + 1);
            }
        }
        System.out.println(f[(1<<m)-1]);
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值