最后一题醉了啊,中文的题意看完一脸懵逼,后期官方把题意改了,可是我已经跑路了啊。。。。
思路:暴力枚举两两乘积即可。
class Solution {
public int maxProduct(int[] nums) {
int ans=0;
for(int i=0;i<nums.length;i++)
for(int j=i+1;j<nums.length;j++)
ans=Math.max(ans, (nums[i]-1)*(nums[j]-1));
return ans;
}
}
思路:其实就是找水平两条线距离的最大值乘以竖直两条线距离的最大值。
class Solution {
public int maxArea(int h, int w, int[] horizontalCuts, int[] verticalCuts) {
int mod=1000000007;
long ans=0;
List<Integer> hh=new ArrayList<>();
List<Integer> ww=new ArrayList<>();
Arrays.parallelSort(horizontalCuts);
Arrays.parallelSort(verticalCuts);
hh.add(0); ww.add(0);
for(int i=0;i<horizontalCuts.length;i++)
hh.add(horizontalCuts[i]);
for(int i=0;i<verticalCuts.length;i++)
ww.add(verticalCuts[i]);
hh.add(h); ww.add(w);
long mx=0;
for(int i=1;i<hh.size();i++)
mx=Math.max(mx, hh.get(i)-hh.get(i-1));
for(int i=1;i<ww.size();i++)
ans=Math.max(ans, mx*(ww.get(i)-ww.get(i-1)));
return (int)(ans%mod);
}
}
思路:这道题其实是可以有很多奇技淫巧的,我采用的方法是将原有向图看成无向图,将原有向边的权值设为1,反过来的边权值设为0,我们选择从0开始出发走到所有点,并标记当前点上一条边的权值是否为1就ok了。之后将所有dis求和就是答案啦,不懂的童鞋可以稍微思考一下,我这里不再过多赘述啦。
class Solution {
class node{
int v,val;
public node(int v,int val) {
this.v=v;
this.val=val;
}
}
int[] dis;
boolean[] flag;
List<List<node>> list;
public int minReorder(int n, int[][] connections) {
dis=new int[n];
flag=new boolean[n];
list=new ArrayList<>();
for(int i=0;i<n;i++) {
dis[i]=500005;
list.add(new ArrayList<>());
}
for(int i=0;i<connections.length;i++) {
list.get(connections[i][0]).add(new node(connections[i][1],1));
list.get(connections[i][1]).add(new node(connections[i][0],0));
}
dfs(0,0);
int ans=0;
for(int i=0;i<n;i++) {
ans+=dis[i];
//System.out.println(dis[i]+" "+i);
}
return ans;
}
private void dfs(int x,int step) {
dis[x]=Math.min(dis[x], step);
flag[x]=true;
for(int i=0;i<list.get(x).size();i++) {
node next=list.get(x).get(i);
if(flag[next.v]) continue;
dfs(next.v,next.val);
}
}
}
PS:不知道一开始的题意怎么想的,我读了几遍后得出的结论是我学了十几年的假语文?后期出题人把题意改了,可是当时我真的已经跑路了,赛后发现了新的题意后有点后悔当时应该关注下比赛的。
思路:题目不难,无非就是考了一点简单的组合数学的知识,核心考察的仍然是动态规划,我们令dp[i][j][k][u][v]表示前i种颜色的球,其中第一个盒子里有j个球,第二个盒子中有k个球,并且第一个盒子颜色数为u,第二个盒子颜色数为v的方案数。
转移方程直接看代码吧,不太能说清楚,不懂的话可以私聊我啦。
class Solution {
private double[][] C;
private double[][][][][] dp;
Solution(){
C=new double[25][25];
dp=new double[9][25][25][9][9];
C[0][0]=1;
dp[0][0][0][0][0]=1;
for(int i=1;i<25;i++) {
C[i][0]=1;
for(int j=1;j<=i;j++)
C[i][j]=C[i-1][j-1]+C[i-1][j];
}
}
public double getProbability(int[] balls) {
int sum=0;
int n=balls.length;
for(int i=0;i<n;i++)
sum+=balls[i];
sum/=2;
for(int i=1;i<=n;i++) {
int t=balls[i-1];
for(int j=sum;j>=t;j--)
for(int k=0;k<=sum;k++)
for(int u=i;u>=1;u--)
for(int v=0;v<=i;v++) {
dp[i][j][k][u][v]+=dp[i-1][j-t][k][u-1][v]*C[j][t];
dp[i][k][j][v][u]+=dp[i-1][k][j-t][v][u-1]*C[j][t];
}
for(int b=1;b<t;b++)
for(int j=sum;j>=b;j--)
for(int k=sum;k>=t-b;k--)
for(int u=i;u>=1;u--)
for(int v=i;v>=1;v--)
dp[i][j][k][u][v]+=dp[i-1][j-b][k-(t-b)][u-1][v-1]
*C[j][b]*C[k][t-b];
}
double ans=0,total=0;
for(int i=0;i<=n;i++) {
ans+=dp[n][sum][sum][i][i];
for(int j=0;j<=n;j++)
total+=dp[n][sum][sum][i][j];
}
return ans/total;
}
}