- 给你一个整数数组coins,表示不同面额的硬币;以及一个整数amount,表示总金额。计算并返回可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回-1。你可以认为每种硬币的数量是无限的。
public int coinChange(int[] coins,int amount){
//连接金币和总金额,数量之间的关系
int[][] dp = new int[coins.length+1][amount+1];
for (int i=0;i<dp.length;i++){
Arrays.fill(dp[i],amount+1);
}
for (int i=0;i<coins.length;i++){
dp[i][0] = 0;
}
for (int i=1;i<=coins.length;i++){
for (int j=0;j<=amount;j++){
for (int k = j/coins[i-1];k>=0;k--){
dp[i][j] = Math.min(dp[i][j],dp[i-1][j-coins[i-1]*k]+k);
}
}
}
return dp[coins.length][amount] == amount+1?-1:dp[coins.length][amount];
}
- 为了不断提高用户使用的体验,开发团队正在对产品进行全方位的开发和优化。
已知开发团队共有若干名成员,skills[i] 表示第 i 名开发人员掌握技能列表。
如果两名成员各自拥有至少一门对方未拥有的技能,则这两名成员可以「合作开发」。
请返回当前有多少对开发成员满足「合作开发」的条件。
由于答案可能很大,请你返回答案对 10^9 + 7 取余的结果。
来自银联编程比赛。
————————————————
版权声明:本文为CSDN博主「福大大架构师每日一题」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_48502062/article/details/125035121
/**
* 合并开发
* @param skills
* @return
* 总数-不合法的 = 合法的
*/
long mod = 1000000007L;
public int coopDevelop(int[][] skills){
int n = skills.length;
//key: 子集
//value: 个数
//连接的是技术和个数
HashMap<Long,Long> noFullSetsNums = new HashMap<>();
for (int[] people : skills){
fillNoFullMap(people,0,0,true,noFullSetsNums);
}
HashMap<Long,Long> cntsNums = new HashMap<>();
long minus = 0L;
for (int[] people:skills){
long status = 0L;
for (int skill:people){
//status连接的是某个人的技术
status = (status<<10) | skill;
}
minus+=noFullSetsNums.getOrDefault(status,0L);
minus+=cntsNums.getOrDefault(status,0L);
cntsNums.put(status,cntsNums.getOrDefault(status,0L)+1);
}
long ans = (long)n*(long)(n-1)/2L;
return (int) ((ans-minus)%mod);
}
public void fillNoFullMap(int[] people,int i,long status,boolean full,HashMap<Long,Long> noFullSetsNums){
if (i==people.length){
if (!full){
noFullSetsNums.put(status,noFullSetsNums.getOrDefault(status,0L)+1);
}
}else {
//
fillNoFullMap(people,i+1,status,false,noFullSetsNums);
//status来连接某个人的技术
fillNoFullMap(people,i+1,(status << 10)|people[i],full,noFullSetsNums);
}
}