problem1 link
两个数字后面都有阶乘符号,可以抵消。
import java.util.*; import java.math.*; import static java.lang.Math.*; public class ExtraordinarilyLarge { public String compare(String x, String y) { boolean both=false; while(x.endsWith("!")&&y.endsWith("!")) { x=x.substring(0,x.length()-1); y=y.substring(0,y.length()-1); both=true; } boolean bswap=false; if(x.endsWith("!")) { String t=new String(x); x=y; y=t; bswap=true; } long xx=Long.valueOf(x); if(xx==0&&both) { xx=1; } long yy=1; if(y.endsWith("!")) { int id=y.indexOf("!"); yy=Long.valueOf(y.substring(0,id)); final int num=y.length()-id; for(int i=0;i<num&&yy<=xx;++i) { yy=cal(yy,xx); } } else { yy=Long.valueOf(y); if(yy==0&&both) { yy=1; } } if(xx<yy) { if(bswap) { return "x>y"; } return "x<y"; } else if(xx==yy) { return "x=y"; } else { if(bswap) { return "x<y"; } return "x>y"; } } long cal(long x,long y) { if(x==0) { return 1; } long result=1; for(int i=2;i<=x;++i) { if(result<=y/i) { result=result*i; } else { return y+1; } } return result; } }
problem2 link
在一个有向无环图上进行dp即可。
import java.util.*; import java.math.*; import static java.lang.Math.*; public class ContestSchedule { public double expectedWinnings(String[] contests) { final int n=contests.length; int[][] p=new int[n][3]; for(int i=0;i<n;++i) { String[] t=contests[i].split("\\W+"); assert t.length==3; for(int j=0;j<3;++j) { p[i][j]=Integer.valueOf(t[j]); } } boolean[][] g=new boolean[n][n]; for(int i=0;i<n;++i) { for(int j=0;j<n;++j) { if(i==j) { g[i][j]=false; continue; } if(p[i][1]<=p[j][0]) { g[i][j]=true; } else { g[i][j]=false; } } } Queue<Integer> queue=new LinkedList<>(); double[] f=new double[n]; boolean[] inq=new boolean[n]; for(int i=0;i<n;++i) { inq[i]=true; f[i]=p[i][2]/100.0; queue.offer(i); } while(!queue.isEmpty()) { final int u=queue.poll(); inq[u]=false; for(int i=0;i<n;++i) { if(g[u][i]) { final double c=p[i][2]/100.0; if(f[u]+c>f[i]) { f[i]=f[u]+c; if(!inq[i]) { inq[i]=true; queue.offer(i); } } } } } double result=0; for(int i=0;i<n;++i) { result=Math.max(result,f[i]); } return result; } }
problem3 link
$n,m$中小的那个必定小于9.这样一行一行进行dp即可。
import com.sun.org.apache.xpath.internal.operations.Bool; import java.util.*; import java.math.*; import static java.lang.Math.*; public class SeatingPlan { public String expectedTrial(int m, int n, int k) { if(n<m) { int x=m; m=n; n=x; } long[][][] f=new long[n+1][1<<m][k+1]; int[] num=new int[1<<m]; num[0]=0; for(int i=1;i<(1<<m);++i) { num[i]=num[i>>1]+(i&1); } List<List> g=new ArrayList<>(); for(int i=0;i<(1<<m);++i) { List<Integer> list=new ArrayList<>(); if(((i>>1)&i)!=0) { g.add(list); continue; } for(int j=0;j<(1<<m);++j) { if((i&j)==0&&((j>>1)&j)==0) { list.add(j); } } g.add(list); } f[0][0][0]=1; for(int i=1;i<=n;++i) { for(int j=0;j<(1<<m);++j) { for(int t=0;t<=k;++t) { if(0==f[i-1][j][t]) { continue; } List list=g.get(j); for(int p=0;p<list.size();++p) { int s=(int)list.get(p); if(t+num[s]>k) { continue; } f[i][s][t+num[s]]+=f[i-1][j][t]; } } } } long result=0; for(int i=0;i<(1<<m);++i) { result+=f[n][i][k]; } if(result==0) { return "Impossible!"; } BigInteger sum=BigInteger.ONE; for(int i=1;i<=k;++i) { sum=sum.multiply(int2biginteger(n*m-i+1)).divide(int2biginteger(i)); } long s=Long.valueOf(sum.toString()); long p=gcd(result,s); result/=p; s/=p; return Long.toString(s)+"/"+Long.toString(result); } static long gcd(long x,long y) { return y==0?x:gcd(y,x%y); } static BigInteger int2biginteger(int x) { return new BigInteger(Integer.toString(x)); } }
时间: 2024-12-08 08:02:24