原题链接:蓝桥杯2019年第十届省赛真题-糖果
解题思路:状态压缩将每种状态用二进制的形式表示
例如第一包糖果:1 1 2
可以表示为:00011
表示第一种和第二种口味都有
而11111表示五种口味都有
dp[j]:表示当j状态的时,最少需要几包糖果构成
状态转移方程:
if(dp[j]==0){
continue;
}else{
if(dp[j | mzhuangtai[i]]==0){
dp[j | mzhuangtai[i]]=dp[j]+dp[mzhuangtai[i]];
}else{
dp[j | mzhuangtai[i]]=Math.min(dp[j | mzhuangtai[i]], dp[j]+dp[mzhuangtai[i]]);
}
}
模拟一下,一个一个进行或运算,最后找到最佳值
参考代码:
import java.util.Scanner; 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(); //n包糖果,m种类,每包k个糖 int[] dp=new int[(1<<m)-1+1]; //dp[i]=value: i状态口味需要value包糖果构成 int[] mzhuangtai=new int[n]; for(int i=0;i<n;i++){ for(int j=0;j<k;j++){ int weidao=sc.nextInt(); mzhuangtai[i] |= 1<<weidao-1; //按位或运算符优先级 低于 加减运输符 } dp[mzhuangtai[i]]=1; } for(int i=0;i<n;i++){ for(int j=0;j<(1<<m);j++){ if(dp[j]==0){ continue; }else{ if(dp[j | mzhuangtai[i]]==0){ dp[j | mzhuangtai[i]]=dp[j]+dp[mzhuangtai[i]]; }else{ dp[j | mzhuangtai[i]]=Math.min(dp[j | mzhuangtai[i]], dp[j]+dp[mzhuangtai[i]]); } } } } System.out.println(dp[(1<<m)-1]==0?-1:dp[(1<<m)-1]); } }
0.0分
4 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复