# AP325 補救計畫(II) 作者:欉恩祁 因為我跟竑誠在APCS被其他人給電爛了,所以決定來寫TCIRC的神奇題目來補救。 [>>Part I](https://hackmd.io/@r1cky/H1n-nQf_Y) --- ## d061~d080 ### d061 監看華山練功場 解法:greedy ```Java= import java.io.*; import java.util.*; public class d061 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r,idx=0,cnt,ans; public static seg p=null; public static boolean so=true; public static void main(String[] args) throws Exception{ final int n=orz(); final int x=orz(); final int y=orz(); seg[] s=new seg[n]; for(int i=0;i<n;i++) { s[i]=new seg(orz(),orz()); } Arrays.sort(s,new Comparator<seg>() { public int compare(seg f,seg s) { return f.l-s.l; } }); PriorityQueue<seg> pq=new PriorityQueue<>(new Comparator<seg>() { public int compare(seg f,seg s) { return f.r-s.r; } }); cnt=x+1; all: while(cnt<y) { while(idx<n&&s[idx].l<=cnt) { pq.offer(s[idx]); idx++; } if(pq.isEmpty()) { so=false; break all; } while(!pq.isEmpty())p=pq.poll(); cnt=p.r; ans++; } if(so) { System.out.println(ans); } else { System.out.println(-1); } } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } class seg{ int l,r; seg(int a,int b){ l=a; r=b; } } ``` --- ### d064 反序數量 解法:BIT ```Java= import java.util.*; import java.io.*; public class d064 { public static int[] bit=new int[1000005]; public static void main(String[] args) throws Exception{ BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); String[] read=br.readLine().split(" "); int t=Integer.parseInt(read[0]); long out=0; int a; read=br.readLine().split(" "); for(int i=0;i<1000005;i++)bit[i]=0; for(int i=t-1;i>=0;i--) { a=Integer.parseInt(read[i]); out+=sum(a); update(a+1); } System.out.println(out); } public static void update(int x) { for(int i=x;i<1000005;i+=i&(-i)) { bit[i]+=1; } } public static int sum(int x) { int r=0; for(int i=x;i>0;i-=i&(-i)) { r+=bit[i]; } return r; } } ``` --- ### d065 大樓外牆廣告 解法:monotone stack(感謝電神thanksone、宗翰提供意見!) ```Java= import java.io.*; import java.util.*; public class d065 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static long mx=0; public static void main(String[] args) throws Exception{ String[] r=br.readLine().split(" "); final int n=Integer.parseInt(r[0]); int id; long in; p po; Stack<p> a=new Stack<>(); int[] h=new int[n]; r=br.readLine().split(" "); for(int i=0;i<n;i++)h[i]=Integer.parseInt(r[i]); for(int i=0;i<n;i++) { in=h[i]; id=i; while(a.size()!=0) { po=a.pop(); if(po.h<in) { a.push(po); break; } if(po.idx<id)id=(int)po.idx; mx=Math.max((i-po.idx)*po.h,mx); } a.push(new p(id,in)); } while(a.size()!=0) { po=a.pop(); mx=Math.max((n-po.idx)*po.h,mx); } System.out.println(mx); } } class p{ long idx,h; p(long a,long b){ idx=a; h=b; } } ``` --- ### d066 小朋友上樓梯最小成本 解法:DP ```Java= import java.io.*; import java.util.*; public class d066 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static void main(String[] args) throws Exception{ final int n=orz(); int[] p=new int[n]; int[] dp=new int[n+1]; for(int i=0;i<n;i++) { p[i]=orz(); } dp[0]=0; dp[1]=p[0]; for(int i=2;i<=n;i++) { dp[i]=Math.min(dp[i-1],dp[i-2])+p[i-1]; } System.out.println(dp[n]); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d067 不連續的表演酬勞 解法:DP ```Java= import java.io.*; import java.util.*; public class d067 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static void main(String[] args) throws Exception{ final int n=orz(); int[] p=new int[n]; int[] dp=new int[n+1]; for(int i=0;i<n;i++) { p[i]=orz(); } dp[0]=0; dp[1]=p[0]; dp[2]=p[1]; for(int i=3;i<=n;i++) { dp[i]=Math.max(dp[i-3],dp[i-2])+p[i-1]; } System.out.println(Math.max(dp[n-1],dp[n])); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d068 最小監控鄰居的成本 解法:DP ```Java= import java.io.*; import java.util.*; public class d068 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static int[][] dp=new int[100005][3]; public static int[] cost=new int[100005]; public static void main(String[] args) throws Exception{ final int n=orz(); for(int i=1;i<=n;i++) { cost[i]=orz(); } dp[0][0]=0; dp[0][1]=1<<30; dp[0][2]=cost[1]; cost[n+1]=cost[n]; for(int i=1;i<=n;i++) { dp[i][0]=dp[i-1][1]; dp[i][1]=dp[i-1][2]; dp[i][2]=Math.min(dp[i-1][0],Math.min(dp[i-1][1],dp[i-1][2]))+cost[i+1]; } System.out.println(Math.min(dp[n][0],Math.min(dp[n][1],dp[n][2]))); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d069 方格棋盤路線 解法:DP ```Java= import java.io.*; import java.util.*; public class d069 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static boolean neg; public static int[][] dp=new int[205][205]; public static int[][] mp=new int[205][205]; public static void main(String[] args) throws Exception{ final int n=orz(); final int m=orz(); for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { mp[i][j]=orz(); } } dp[0][0]=mp[0][0]; for(int i=1;i<m;i++) { dp[0][i]=dp[0][i-1]+mp[0][i]; } for(int i=1;i<n;i++) { dp[i][0]=dp[i-1][0]+mp[i][0]; } for(int i=1;i<n;i++) { for(int j=1;j<m;j++) { dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1])+mp[i][j]; } } System.out.println(dp[n-1][m-1]); } public static int orz() throws Exception{ ret=0; r=br.read(); neg=false; if(r=='-') { neg=true; r=br.read(); } while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } if(neg)ret*=-1; return ret; } } ``` --- ### d070 LCS 解法:LCS ```Java= import java.io.*; import java.util.*; public class d070 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static boolean neg; public static int[][] dp=new int[505][505]; public static void main(String[] args) throws Exception{ String a=br.readLine(); String b=br.readLine(); final int m=a.length()+1; final int n=b.length()+1; for(int i=1;i<m;i++) { for(int j=1;j<n;j++) { if(a.charAt(i-1)==b.charAt(j-1)) { dp[i][j]=dp[i-1][j-1]+1; } else { dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1]); } } } System.out.println(dp[m-1][n-1]); } } ``` --- ### d071 大賣場免費大搬家 解法:背包低批 ```Java= import java.io.*; import java.util.*; public class d071 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static void main(String[] args) throws Exception{ final int n=orz(); final int l=orz(); int[] dp=new int[l+1]; Arrays.fill(dp,0); int[] w=new int[n]; int[] v=new int[n]; for(int i=0;i<n;i++)w[i]=orz(); for(int i=0;i<n;i++)v[i]=orz(); for(int i=0;i<n;i++) { for(int j=l;j>=w[i];j--) { dp[j]=Math.max(dp[j-w[i]]+v[i],dp[j]); } } System.out.println(dp[l]); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d072 闖關二選一 解法:DP ```Java= import java.io.*; import java.util.*; public class d072 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static boolean neg; public static int[][] dp=new int[100005][2]; public static int[][] mp=new int[100005][2]; public static void main(String[] args) throws Exception{ final int n=orz(); final int t=orz(); for(int i=1;i<=n;i++) { mp[i][0]=orz(); mp[i][1]=orz(); } mp[0][0]=mp[0][1]=t; for(int i=1;i<=n;i++) { dp[i][0]=Math.min(dp[i-1][0]+Math.abs(mp[i][0]-mp[i-1][0]),dp[i-1][1]+Math.abs(mp[i][0]-mp[i-1][1])); dp[i][1]=Math.min(dp[i-1][0]+Math.abs(mp[i][1]-mp[i-1][0]),dp[i-1][1]+Math.abs(mp[i][1]-mp[i-1][1])); } System.out.println(Math.min(dp[n][0],dp[n][1])); } public static int orz() throws Exception{ ret=0; r=br.read(); neg=false; if(r=='-') { neg=true; r=br.read(); } while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } if(neg)ret*=-1; return ret; } } ``` --- ### d073 二維最大子矩陣 解法:一軸DP另一軸暴力、前綴和 ```Java= import java.io.*; public class d073 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int max=0,id=0; public static boolean neg; public static int[] dp=new int[2]; public static int[][] msum=new int[205][205]; public static void main(String[] args) throws Exception{ String[] r=br.readLine().split(" "); final int n=Integer.parseInt(r[0]); final int m=Integer.parseInt(r[1]); for(int i=0;i<n;i++) { r=br.readLine().split(" "); for(int j=1;j<=m;j++) { msum[i][j]=msum[i][j-1]+Integer.parseInt(r[j-1]); } } for(int i=0;i<m;i++) { for(int j=i+1;j<=m;j++) { id=0; dp[0]=dp[1]=0; for(int k=0;k<n;k++) { dp[id^1]=Math.max(dp[id],0)+msum[k][j]-msum[k][i]; max=Math.max(max,dp[id^1]); id^=1; } } } System.out.println(max); } } ``` --- ### d074 Local alignment 解法:DP、生物學(?) ```Java= import java.io.*; public class d074 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int max=0; public static int[][] dp=new int[505][505]; public static void main(String[] args) throws Exception{ String a=br.readLine(); String b=br.readLine(); final int m=a.length()+1; final int n=b.length()+1; for(int i=1;i<m;i++) { for(int j=1;j<n;j++) { if(a.charAt(i-1)==b.charAt(j-1)) { dp[i][j]=dp[i-1][j-1]+8; if(dp[i][j]>max)max=dp[i][j]; } else { dp[i][j]=Math.max(dp[i-1][j-1]-5,Math.max(dp[i-1][j]-3,dp[i][j-1]-3)); if(dp[i][j]>max)max=dp[i][j]; if(dp[i][j]<0)dp[i][j]=0; } } } System.out.println(max); } } ``` --- ### d076 Catalan number 解法:Catalan number ```Java= import java.io.*; import java.math.BigInteger; import java.util.*; public class d076 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static void main(String[] args) throws Exception{ String[] in=br.readLine().split(" "); final int n=Integer.parseInt(in[0]); BigInteger a=new BigInteger("1"); BigInteger b=new BigInteger("1"); BigInteger p=new BigInteger("1000000009"); for(int i=1;i<=n+1;i++) { a=a.multiply(new BigInteger(Integer.toString(i))); } for(int i=n+1;i<=2*n;i++) { b=b.multiply(new BigInteger(Integer.toString(i))); } System.out.println((b.divide(a)).mod(p)); } } ``` --- ### d077 周伯通的基地台 解法:博愛排隊 ```Java= import java.io.*; import java.util.*; public class d077 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static void main(String[] args) throws Exception{ final int n=orz(); final int k=orz(); int in; dp p; PriorityQueue<dp> pq=new PriorityQueue<>(new Comparator<dp>() { public int compare(dp f,dp s) { return f.cost-s.cost; } }); pq.offer(new dp(-1,0)); for(int i=0;i<n;i++) { in=orz(); while(!pq.isEmpty()) { p=pq.poll(); if(p.mx+1>=i-k) { pq.offer(p); pq.offer(new dp(i+k,p.cost+in)); break; } } } while(!pq.isEmpty()) { p=pq.poll(); if(p.mx+1>=n) { System.out.println(p.cost); break; } } } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } class dp{ int mx,cost; dp(int a,int b){ mx=a; cost=b; } } ``` --- ### d078 一覽衆山小 解法:LCS ```Java= import java.io.*; import java.util.*; public class d078 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static void main(String[] args) throws Exception{ final int n=orz(); int in,bis; ArrayList<Integer> a=new ArrayList<Integer>(); for(int i=0;i<n;i++) { in=orz(); bis=Collections.binarySearch(a,in); if(bis<0) { bis=bis*-1-1; if(bis==a.size()) { a.add(in); } else { a.set(bis,in); } } } System.out.println(a.size()); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d079 切棍子 解法:DP、遞迴 ```Java= import java.io.*; import java.util.*; public class d079 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static int[][] dp=new int[205][205]; public static int[] mp=new int[205]; public static void main(String[] args) throws Exception{ final int n=orz(); final int l=orz(); mp[0]=0; mp[n+1]=l; for(int i=1;i<=n;i++) { mp[i]=orz(); } System.out.println(query(1,n)); } public static int query(int l,int r) { if(l>r)return 0; if(dp[l][r]!=0) return dp[l][r]; if(l==r) { dp[l][r]=mp[l+1]-mp[l-1]; return dp[l][r]; } int mn=1<<30; for(int i=l;i<=r;i++) { mn=Math.min(mn,query(l,i-1)+query(i+1,r)+mp[r+1]-mp[l-1]); } dp[l][r]=mn; return dp[l][r]; } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d080 階梯數字 解法:遞迴 ```Java= import java.util.*; import java.io.*; public class d080 { public static int out=0; public static byte end=0; public static byte[] lim; public static void main(String[] args) throws Exception{ BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); String[] read=br.readLine().split(" "); end=(byte)read[0].length(); long num=Long.parseLong(read[0]); int c=0; lim=new byte[100]; for(int i=1;i<=end;i++) { lim[i]=(byte)(num/(long)(Math.pow(10,end-i))%10); } find((byte)0,(byte)0,true); System.out.println(out-1); } public static void find(byte x,byte cl,boolean b) { if(cl==end) { out++; return; } else { cl++; for(byte i=x;i<10;i++) { if(b) { if(i<lim[cl]) { find(i,(byte)cl,false); } else if(i==lim[cl]) { find(i,(byte)cl,true); } else return; } else find(i,(byte)cl,false); } } } } ``` --- ## d081~d100 ### d081 Hyper-cube path 解法:DP ```Java= import java.io.*; public class d081 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static int[] dp=new int[1<<20]; public static void main(String[] args) throws Exception{ final int n=orz(); int mx,d,lowbit; for(int i=0;i<(1<<n);i++) { d=i; mx=0; while(d!=0) { lowbit=d&(-d); d-=lowbit; mx=Math.max(mx,dp[i-lowbit]); } dp[i]=mx+orz(); } System.out.println(dp[(1<<n)-1]); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d082 刪除邊界 解法:DP、遞迴 ```Java= import java.io.*; import java.util.*; public class d082 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r,cnt,c; public static int[][][][] dp=new int[35][35][35][35]; public static boolean[][] mp=new boolean[35][35]; public static void main(String[] args) throws Exception{ final int m=orz(); final int n=orz(); for(int i=0;i<m;i++) { for(int j=0;j<n;j++) { mp[i][j]=(orz()==1)?true:false; } } for(int i=0;i<30;i++)for(int j=0;j<30;j++)for(int k=0;k<30;k++)for(int l=0;l<30;l++)dp[i][j][k][l]=-1; System.out.println(q(0,m-1,0,n-1)); } public static int q(int lx,int rx,int ly,int ry) { if(lx==rx||ly==ry)return 0; if(dp[lx][rx][ly][ry]!=-1)return dp[lx][rx][ly][ry]; int min=1<<30; min=Math.min(q(lx+1,rx,ly,ry)+mn(lx,lx,ly,ry),min); min=Math.min(q(lx,rx-1,ly,ry)+mn(rx,rx,ly,ry),min); min=Math.min(q(lx,rx,ly+1,ry)+mn(lx,rx,ly,ly),min); min=Math.min(q(lx,rx,ly,ry-1)+mn(lx,rx,ry,ry),min); dp[lx][rx][ly][ry]=min; return dp[lx][rx][ly][ry]; } public static int mn(int lx,int rx,int ly,int ry) { if(dp[lx][rx][ly][ry]!=-1)return dp[lx][rx][ly][ry]; cnt=c=0; for(int i=lx;i<=rx;i++) { for(int j=ly;j<=ry;j++) { if(mp[i][j])cnt++; else c++; } } dp[lx][rx][ly][ry]=Math.min(c,cnt); return dp[lx][rx][ly][ry]; } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d083 文無第一武無第二 解法:單調序列、LIS、二分搜 ```Java= import java.io.*; import java.util.*; public class d083 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r,ans=0; public static int[][] in; public static void main(String[] args) throws Exception{ final int n=orz(); int l,r,m,preval; ArrayList<pair> a=new ArrayList<>(); a.add(new pair(-2,0)); a.add(new pair(Integer.MAX_VALUE,Integer.MAX_VALUE)); in=new int[n][3]; for(int i=0;i<3;i++) { for(int j=0;j<n;j++)in[j][i]=orz(); } Arrays.sort(in,new Comparator<int[]>() { public int compare(int[] f,int[] s) { if(f[1]!=s[1])return (s[1]-f[1]); return (f[2]-s[2]); } }); for(int i=0;i<n;i++) { l=0; r=a.size()-1; while(l!=r) { m=(l+r+1)/2; if(a.get(m).idx>in[i][2]) { r=m-1; } else { l=m; } } preval=in[i][0]+a.get(l).val; l=0; r=a.size()-1; while(l!=r) { m=(l+r)/2; if(a.get(m).val>=preval) { r=m; } else { l=m+1; } } if(a.get(l).idx<=in[i][2])continue; a.add(l,new pair(in[i][2],preval)); l--; while(a.get(l).idx>=in[i][2]) { a.remove(l); l--; } ans=Math.max(ans,preval); } System.out.println(ans); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } class pair{ int idx,val; pair(int a,int b){ idx=a; val=b; } } ``` --- ### d084 楊鐵心做 1 休 K 解法:Queue、greedy ```Java= import java.io.*; import java.util.*; public class d084 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r,in,p,max; public static void main(String[] args) throws Exception{ final int n=orz(); final int k=orz(); Queue<Integer> q=new LinkedList<>(); for(int i=0;i<k;i++) { q.offer(0); } for(int i=0;i<n;i++) { in=orz(); q.offer(max+in); p=q.poll(); if(p>max)max=p; } while(!q.isEmpty()) { p=q.poll(); if(p>max)max=p; } System.out.println(max); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d085 K次買賣 O(nk) 解法:DP ```Java= import java.io.*; import java.util.*; public class d085 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r,x=0,in; public static long[][][] dp=new long[2][205][2]; public static void main(String[] args) throws Exception{ final int n=orz(); final int k=orz(); dp[0][0][1]=-(1<<30); dp[1][0][1]=-(1<<30); for(int i=0;i<n;i++) { in=orz(); for(int j=0;j<k;j++) { dp[x^1][j][1]=Math.max(dp[x][j][0]-in,dp[x][j][1]); dp[x^1][j+1][0]=Math.max(dp[x][j][1]+in,dp[x][j+1][0]); } x^=1; } System.out.println(dp[x][k][0]); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d086 矩陣乘法鏈 解法:DP ```Java= import java.io.*; import java.util.*; public class d086 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static int[][] dp=new int[205][205]; public static int[] in=new int[205]; public static void main(String[] args) throws Exception{ final int n=orz(); for(int i=0;i<=n;i++)in[i]=orz(); System.out.println(rec(0,n-1)); } public static int rec(int l,int r) { if(dp[l][r]!=0)return dp[l][r]; if(l>=r)return 0; int mn=1<<30; for(int i=l;i<r;i++) { mn=Math.min(mn,rec(l,i)+rec(i+1,r)+in[l]*in[i+1]*in[r+1]); } dp[l][r]=mn; return mn; } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d087 直升機抓寶 解法:LIS ```Java= import java.io.*; import java.util.*; public class d087 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static void main(String[] args) throws Exception{ final int n=orz(); int l,r,m,a=0,b=0; ArrayList<Integer> lis=new ArrayList<>(); lis.add(-1); lis.add(1<<30); for(int i=0;i<n;i++) { a=orz(); b=orz(); l=0; r=lis.size()-1; while(l!=r) { m=(l+r)/2; if(lis.get(m)<=a) { l=m+1; } else { r=m; } } lis.add(l,a); l--; r=lis.size()-1; while(l!=r) { m=(l+r)/2; if(lis.get(m)<=b) { l=m+1; } else { r=m; } } if(l!=lis.size()-1)lis.remove(l); } System.out.println(lis.size()-2); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } //參考:https://emanlaicepsa.github.io/2020/12/07/0-20/ ``` --- ### d088 隔離採礦 解法:Monotone stack、DP、Priority queue ```Java= import java.io.*; import java.util.*; import java.math.*; public class d088 { public static int re,ret,mx,ans,idx=0; public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out)); public static int[] h=new int[1000005]; public static void main(String[] args) throws Exception{ final int n=orz(); int v; pii p; pii[] a=new pii[1000005]; a[0]=new pii(1<<30,0); PriorityQueue<pii> pq=new PriorityQueue<>(new Comparator<pii>() { public int compare(pii f,pii s) { return f.h-s.h; } }); for(int i=0;i<n;i++)h[i]=orz(); for(int i=0;i<n;i++) { v=orz(); mx=-1; while(!pq.isEmpty()) { p=pq.poll(); if(p.h>=h[i]) { pq.offer(p); break; } mx=Math.max(mx,p.v); } while(a[idx].h<=h[i]) { mx=Math.max(mx,a[idx].v); idx--; } mx=Math.max(mx,a[idx].v); pq.offer(new pii(h[i],a[idx].v+v)); if(a[idx].v<mx)a[++idx]=new pii(h[i],mx); } for(int i=0;i<=idx;i++) { ans=Math.max(a[i].v,ans); } while(!pq.isEmpty()) { ans=Math.max(pq.poll().v,ans); } System.out.println(ans); } public static int orz()throws Exception { ret=0; re=br.read(); while(re>47&&re<58) { ret*=10; ret+=(re&15); re=br.read(); } return ret; } } class pii{ int h,v; pii(int a,int b){ h=a; v=b; } } ``` --- ### d089 貨郎問題 解法:位元低批 ```Java= import java.io.*; import java.util.*; public class d089 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static final int inf=1<<30; public static int[][] cost=new int[16][16]; public static int[][] dp=new int[1<<16][16]; public static void main(String[] args) throws Exception{ final int n=orz(); orz(); int mn; for(int i=0;i<n;i++)for(int j=0;j<n;j++)cost[i][j]=orz(); for(int i=1;i<n;i++)dp[0][i]=inf; for(int i=1;i<(1<<n);i++) { for(int j=0;j<n;j++) { if((i&(1<<j))==0) { dp[i][j]=inf; } else { mn=inf; for(int k=0;k<n;k++) { mn=Math.min(mn,dp[i-(1<<j)][k]+cost[k][j]); } dp[i][j]=mn; } } } System.out.println(dp[(1<<n)-1][0]); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d090 機器人走棋盤 解法:bfs ```Java= import java.io.*; import java.util.*; public class d090 implements Runnable{ static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); static int ret,r,cnt=0,ans=0; static ArrayList<ArrayList<Integer>> a=new ArrayList<>(); static boolean[] vis=new boolean[105]; public static void main(String[] args) throws Exception{ new Thread(null,new d090(),"",1<<26).start(); } public void run() { final int n=orz(); final int m=orz(); final int s=orz(); int p,d=1; for(int i=0;i<n;i++)a.add(new ArrayList<Integer>()); for(int i=0;i<m;i++) { a.get(orz()).add(orz()); } Queue<Integer> q=new LinkedList<>(); vis[s]=true; q.offer(s); q.offer(-1); while(!q.isEmpty()) { p=q.poll(); if(p==-1) { d++; if(!q.isEmpty())q.offer(-1); continue; } for(int i:a.get(p)) { if(!vis[i]) { cnt++; ans+=d; vis[i]=true; q.offer(i); } } } System.out.println(cnt); System.out.println(ans); } static int orz(){ ret=0; try { r=br.read(); } catch (IOException e) { e.printStackTrace(); } while(r>47&&r<58) { ret*=10; ret+=(r&15); try { r=br.read(); } catch (IOException e) { e.printStackTrace(); } } return ret; } } ``` --- ### d091 開車蒐集寶物 解法:dfs ```Java= import java.io.*; import java.util.*; public class d091 implements Runnable{ static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); static int ret,r,cnt,ans=0; static ArrayList<ArrayList<Integer>> a=new ArrayList<>(); static boolean[] vis=new boolean[50005]; static int[] v=new int[50005]; public static void main(String[] args) throws Exception{ new Thread(null,new d091(),"",1<<26).start(); } public void run() { final int n=orz(); final int m=orz(); int x,y; for(int i=0;i<n;i++) { a.add(new ArrayList<Integer>()); v[i]=orz(); } for(int i=0;i<m;i++) { x=orz(); y=orz(); a.get(x).add(y); a.get(y).add(x); } for(int i=0;i<n;i++) { cnt=0; dfs(i); if(ans<cnt)ans=cnt; } System.out.println(ans); } static void dfs(int x) { if(vis[x])return; cnt+=v[x]; vis[x]=true; for(int i:a.get(x)) { dfs(i); } } static int orz(){ ret=0; try { r=br.read(); } catch (IOException e) { e.printStackTrace(); } while(r>47&&r<58) { ret*=10; ret+=(r&15); try { r=br.read(); } catch (IOException e) { e.printStackTrace(); } } return ret; } } ``` --- ### d092 機器人走棋盤 解法:dfs ```Java= import java.util.*; import java.io.*; public class d092 { public static void main(String[] args) throws Exception{ BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); String[] read=br.readLine().split(" "); int xr=Integer.parseInt(read[0]); int yr=Integer.parseInt(read[1]); int[][] mp=new int[xr+2][yr+2]; final int max=200000000; int min=max; int px=0,py=0; for(int i=0;i<=xr+1;i++) { for(int j=0;j<=yr+1;j++) { mp[i][j]=max; } } for(int i=1;i<=xr;i++) { read=br.readLine().split(" "); for(int j=1;j<=yr;j++) { mp[i][j]=Integer.parseInt(read[j-1]); if(min>mp[i][j]) { min=mp[i][j]; px=i; py=j; } } } long out=min; int[] go=new int[4]; mp[px][py]=max; while(true) { min=max; go[0]=mp[px+1][py]; go[1]=mp[px-1][py]; go[2]=mp[px][py+1]; go[3]=mp[px][py-1]; int dir=-1; for(int i=0;i<4;i++) { if(min>go[i]) { dir=i; min=go[i]; } } if(dir==-1)break; if(dir==0)px++; if(dir==1)px--; if(dir==2)py++; if(dir==3)py--; mp[px][py]=max; out+=min; } System.out.println(out); } } ``` --- ### d093 方格棋盤的最少轉彎數路線 解法:BFS ```Java= import java.io.*; import java.util.*; public class d093 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static boolean[][] mp=new boolean[505][505]; public static void main(String[] args) throws Exception{ String[] in=br.readLine().split(" "); final int n=Integer.parseInt(in[0]); final int m=Integer.parseInt(in[1]); int ans=-1,x,y; pos p; for(int i=1;i<=n;i++) { in=br.readLine().split(""); for(int j=1;j<=m;j++) { if(in[j-1].equals("0"))mp[i][j]=true; } } Queue<pos> q=new LinkedList<>(); q.offer(new pos(1,1)); mp[1][1]=false; q.offer(new pos(-1,-1)); while(!q.isEmpty()) { p=q.poll(); if(p.x==-1) { if(q.isEmpty()) { ans=-1; break; } ans++; q.offer(p); continue; } if(p.x==n&&p.y==m)break; x=p.x+1; y=p.y; while(mp[x][y]) { mp[x][y]=false; q.offer(new pos(x,y)); x++; } x=p.x-1; y=p.y; while(mp[x][y]) { mp[x][y]=false; q.offer(new pos(x,y)); x--; } x=p.x; y=p.y+1; while(mp[x][y]) { mp[x][y]=false; q.offer(new pos(x,y)); y++; } x=p.x; y=p.y-1; while(mp[x][y]) { mp[x][y]=false; q.offer(new pos(x,y)); y--; } } if(ans!=-1)System.out.println(ans); else { System.out.println(-1); } } } class pos{ int x,y; pos(int a,int b){ x=a; y=b; } } ``` --- ### d094 闖關路線 解法:BFS ```Java= import java.io.*; import java.util.*; public class d094 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r,cnt=0; public static boolean neg; public static int[] mp=new int[1000005]; public static boolean[] vis=new boolean[1000005]; public static void main(String[] args) throws Exception{ final int n=orz(); final int p=orz(); final int l=orz(); final int r=orz(); int pl,m; for(int i=0;i<n;i++)mp[i]=orz(); Queue<Integer> q=new LinkedList<>(); vis[0]=true; q.offer(0); q.offer(-1); while(!q.isEmpty()) { pl=q.poll(); if(pl==p)break; if(pl==-1) { if(q.isEmpty()) { cnt=-1; break; } cnt++; q.offer(-1); continue; } if(pl-l>=0) { m=mp[pl-l]; if(m>=0&&m<n) { if(!vis[m]){ q.offer(m); vis[m]=true; } } } if(pl+r<n) { m=mp[pl+r]; if(m>=0&&m<n) { if(!vis[m]){ q.offer(m); vis[m]=true; } } } } System.out.println(cnt); } public static int orz() throws Exception{ ret=0; r=br.read(); neg=false; if(r=='-') { neg=true; r=br.read(); } while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } if(neg)ret*=-1; return ret; } } ``` --- ### d095 DAG 的最長與最短路徑 解法:DP ```Java= import java.io.*; import java.util.*; public class d095 implements Runnable{ static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); static int ret,r,s,b,c,d; static boolean neg,e=false; static ArrayList<ArrayList<pair>> a=new ArrayList<>(); static int[] min=new int[100005]; static int[] max=new int[100005]; static boolean[] vis=new boolean[100005]; public static void main(String[] args) throws Exception{ new Thread(null,new d095(),"",1<<26).start(); } public void run() { final int n=orz(); final int m=orz(); s=orz(); final int t=orz(); Arrays.fill(min,1<<30); Arrays.fill(max,1<<30); for(int i=0;i<n;i++)a.add(new ArrayList<pair>()); for(int i=0;i<m;i++) { b=orz(); c=orz(); d=orz(); a.get(c).add(new pair(b,d)); } dfs(t); if(e) { System.out.println(min[t]); System.out.println(max[t]); } else { System.out.println("No path"); System.out.println("No path"); } } static pair dfs(int x) { if(x==s)return new pair(0,0); if(vis[x]) { e=true; return new pair(min[x],max[x]); } vis[x]=true; int mn=1<<30,mx=-(1<<30); pair q; for(pair i:a.get(x)) { q=dfs(i.x); mn=Math.min(q.x+i.y,mn); mx=Math.max(q.y+i.y,mx); } min[x]=mn; max[x]=mx; return new pair(mn,mx); } static int orz(){ ret=0; neg=false; try {r=br.read(); } catch (Exception e) {} if(r=='-') { neg=true; try {r=br.read(); } catch (Exception e) {} } while(r>47&&r<58) { ret*=10; ret+=(r&15); try {r=br.read(); } catch (Exception e) {} } if(neg)ret*=-1; return ret; } } class pair{ int x,y; pair(int a,int b){ x=a; y=b; } } ``` --- ### d096 最短路徑 解法:Dijkstra's Algorithm ```Java= import java.util.*; import java.io.*; public class d096 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r,mx=0,cnt=0; public static boolean[] vis=new boolean[100005]; public static ArrayList<ArrayList<P>> a=new ArrayList<>(); public static void main(String[] args) throws Exception{ final int n=orz(); final int m=orz(); int x,y,z; P pl; PriorityQueue<P> pq=new PriorityQueue<>(new Comparator<P>() { public int compare(P f,P s) { return f.w-s.w; } }); for(int i=0;i<n;i++)a.add(new ArrayList<P>()); for(int i=0;i<m;i++) { x=orz(); y=orz(); z=orz(); a.get(x).add(new P(y,z)); a.get(y).add(new P(x,z)); } pq.offer(new P(0,0)); while(!pq.isEmpty()) { pl=pq.poll(); if(vis[pl.n])continue; vis[pl.n]=true; mx=Math.max(mx,pl.w); for(P i:a.get(pl.n)) { pq.offer(new P(i.n,pl.w+i.w)); } } for(int i=0;i<n;i++)if(!vis[i])cnt++; System.out.println(mx); System.out.println(cnt); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } class P{ int n,w; P(int a,int b){ n=a; w=b; } } ``` --- ### d097 挖坑跳 解法:DSU ```Java= import java.io.*; import java.util.*; public class d097 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r,cnt=0,max=0,ta=0,tn=0; public static boolean[][] w=new boolean[505][505]; public static int[][] a=new int[505][505]; public static P[][] dsu=new P[505][505]; public static P top,aa; public static void main(String[] args) throws Exception{ final int m=orz(); final int n=orz(); final int k=orz(); for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) dsu[i][j]=new P(i,j); for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) { if(orz()==1) { cnt++; a[i][j]=1; w[i][j]=true; aa=new P(i,j); if(w[i-1][j])union(aa,new P(i-1,j)); if(w[i+1][j])union(aa,new P(i+1,j)); if(w[i][j-1])union(aa,new P(i,j-1)); if(w[i][j+1])union(aa,new P(i,j+1)); } } } tn+=cnt; ta+=max; int i=0,j=0; for(int q=0;q<k;q++) { i=orz(); j=orz(); if(!w[i][j]) { cnt++; a[i][j]=1; w[i][j]=true; aa=new P(i,j); if(w[i-1][j])union(aa,new P(i-1,j)); if(w[i+1][j])union(aa,new P(i+1,j)); if(w[i][j-1])union(aa,new P(i,j-1)); if(w[i][j+1])union(aa,new P(i,j+1)); } tn+=cnt; ta+=max; } System.out.println(ta); System.out.println(tn); } public static void union(P f,P s) { query(f); query(s); P u=dsu[f.x][f.y]; P v=dsu[s.x][s.y]; if(u.x==v.x&&u.y==v.y) { return; } cnt--; if(u.x*1000+v.y>u.x*1000+v.y) { dsu[u.x][u.y]=new P(v.x,v.y); a[v.x][v.y]+=a[u.x][u.y]; max=Math.max(a[v.x][v.y],max); } else { dsu[v.x][v.y]=new P(u.x,u.y); a[u.x][u.y]+=a[v.x][v.y]; max=Math.max(a[u.x][u.y],max); } } public static void query(P a) { if(dsu[a.x][a.y].x==a.x&&dsu[a.x][a.y].y==a.y) { top=new P(a.x,a.y); return; } query(dsu[a.x][a.y]); dsu[a.x][a.y]=new P(top.x,top.y); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } class P{ int x,y; P(int a,int b){ x=a; y=b; } } ``` --- ### d098 最小生成樹 解法:Kruskal's algorithm ```Java= import java.io.*; import java.util.*; public class d098 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r,cnt=0,cost=0,top,idx=0; public static int[] dsu=new int[100005]; public static ArrayList<P> a=new ArrayList<>(); public static void main(String[] args) throws Exception{ final int n=orz(); final int m=orz(); for(int i=0;i<n;i++)dsu[i]=i; for(int i=0;i<m;i++) { a.add(new P(orz(),orz(),orz())); } Collections.sort(a,new Comparator<P>() { public int compare(P f,P s) { return f.w-s.w; } }); for(;idx<m;idx++) { if(cnt==n-1)break; union(a.get(idx).x,a.get(idx).y); } if(cnt==n-1) { System.out.println(cost); } else { System.out.println(-1); } } public static void union(int f,int s) { query(f); query(s); if(dsu[f]==dsu[s])return; cnt++; cost+=a.get(idx).w; if(dsu[f]>dsu[s]) { dsu[dsu[s]]=dsu[f]; } else { dsu[dsu[f]]=dsu[s]; } } public static void query(int x) { if(dsu[x]==x) { top=x; return; } query(dsu[x]); dsu[x]=top; } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } class P{ int x,y,w; P(int a,int b,int c){ x=a; y=b; w=c; } } ``` --- ### d099 AOV 最早完工時間 解法:DP ```Java= import java.io.*; import java.util.*; public class d099 implements Runnable{ static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); static BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out)); static int ret,r; static ArrayList<ArrayList<Integer>> e=new ArrayList<>(); static ArrayList<ArrayList<Integer>> e2=new ArrayList<>(); static ArrayList<Integer> out=new ArrayList<>(); static int[] dp=new int[10005]; static int[] ct=new int[10005]; public static void main(String[] args) throws Exception{ new Thread(null,new d099(),"",1<<26).start(); } public void run() { final int n=orz(); final int m=orz(); int a,b,pre=-1; for(int i=0;i<=n+1;i++)e.add(new ArrayList<Integer>()); for(int i=0;i<=n+1;i++)e2.add(new ArrayList<Integer>()); for(int i=1;i<=n;i++)ct[i]=orz(); for(int i=0;i<m;i++) { a=orz(); b=orz(); e.get(b).add(a); } for(int i=1;i<=n;i++) { e.get(n+1).add(i); } System.out.println(dfs(n+1)); for(int i:e2.get(n+1)) { dfs2(i); } Collections.sort(out); for(int i:out) { if(pre==i)continue; pre=i; try { bw.write(i+" "); } catch (IOException e) {} } try { bw.flush(); } catch (IOException e) {} } static int dfs(int x) { if(dp[x]!=0)return dp[x]; int mx=ct[x],c; for(int i:e.get(x)) { c=dfs(i)+ct[x]; if(c==mx) { e2.get(x).add(i); } else if(c>mx) { mx=c; e2.get(x).clear(); e2.get(x).add(i); } } dp[x]=mx; return dp[x]; } static void dfs2(int x) { out.add(x); for(int i:e2.get(x)) { dfs2(i); } } static int orz() { ret=0; try {r=br.read(); } catch (Exception e) {} while(r>47&&r<58) { ret*=10; ret+=(r&15); try {r=br.read(); } catch (Exception e) {} } return ret; } } ``` --- ### d100 小寶的著色問題 解法:二分圖判斷 ```Java= import java.io.*; import java.util.*; public class d100 implements Runnable{ static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); static BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out)); static ArrayList<ArrayList<Integer>> e=new ArrayList<>(); static boolean solve; static int ret,r; static int[] vis=new int[10005]; public static void main(String[] args) throws Exception{ new Thread(null,new d100(),"",1<<26).start(); } public void run() { final int t=orz(); int n,m,a,b; for(int i=0;i<t;i++) { e.clear(); Arrays.fill(vis,-1); n=orz(); m=orz(); solve=true; for(int j=0;j<n;j++)e.add(new ArrayList<Integer>()); for(int j=0;j<m;j++) { a=orz(); b=orz(); e.get(a).add(b); e.get(b).add(a); } for(int j=0;j<n;j++) { if(vis[j]==-1)dfs(j,1); if(!solve)break; } if(solve)System.out.println("yes"); else { System.out.println("no"); } } } static void dfs(int x,int pre) { if(vis[x]!=-1) { if(vis[x]==pre)solve=false; return; } vis[x]=pre^1; for(int i:e.get(x)) { dfs(i,vis[x]); } } static int orz() { ret=0; try {r=br.read(); } catch (Exception e) {} while(r>47&&r<58) { ret*=10; ret+=(r&15); try {r=br.read(); } catch (Exception e) {} } return ret; } } ``` --- ## d101~last ### d101 紅白彩帶 解法:DSU+二分搜 ```Java= import java.io.*; import java.util.*; public class d101 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r,top,max=1,ta=0,tb=0,bis; public static boolean[] f=new boolean[100005]; public static int[] l=new int[100005]; public static int[] dsu=new int[100005]; public static ArrayList<Integer> min=new ArrayList<>(); public static void main(String[] args) throws Exception{ final int n=orz(); final int k=orz(); int in; for(int i=1;i<=n;i++) { dsu[i]=i; f[i]=(orz()==1)?true:false; if(f[i]) { l[i]=1; min.add(0,1); if(f[i-1]) { union(i-1,i); } } } ta+=max; tb+=min.get(0); for(int i=0;i<k;i++) { in=orz(); f[in]=true; l[in]=1; min.add(0,1); if(f[in+1])union(in,in+1); if(f[in-1])union(in-1,in); ta+=max; tb+=min.get(0); } System.out.println(ta); System.out.println(tb); } public static void union(int f,int s) { query(f); query(s); bis=Collections.binarySearch(min,l[dsu[f]]); min.remove(bis); bis=Collections.binarySearch(min,l[dsu[s]]); min.remove(bis); l[dsu[f]]+=l[dsu[s]]; bis=Collections.binarySearch(min,l[dsu[f]]); if(bis<0)bis=bis*-1-1; min.add(bis,l[dsu[f]]); dsu[dsu[s]]=dsu[f]; if(max<l[dsu[f]])max=l[dsu[f]]; } public static void query(int x) { if(dsu[x]==x) { top=x; return; } query(dsu[x]); dsu[x]=top; } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d102 樹上的推銷員 解法:DFS ```Java= import java.util.*; import java.io.*; public class d102 implements Runnable{ public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out)); public static int ret,r,cnt=0,x,y; public static ArrayList<Integer> out=new ArrayList<>(); public static ArrayList<ArrayList<Integer>> a=new ArrayList<>(); public static void main(String[] args) throws Exception{ new Thread(null,new d102(),"",1<<26).start(); } public void run() { final int n=orz(); for(int i=0;i<n;i++)a.add(new ArrayList<Integer>()); for(int i=0;i<n-1;i++) { x=orz(); y=orz(); a.get(x).add(y); a.get(y).add(x); cnt+=(orz()*2); } dfs(0,-1); try {bw.write(cnt+"\n");} catch (IOException e) {} for(int i:out) { try {bw.write(i+" ");} catch (IOException e) {} } try {bw.flush();} catch (IOException e) {} } void dfs(int x,int pre) { out.add(x); Collections.sort(a.get(x)); for(int i:a.get(x)) { if(i==pre)continue; dfs(i,x); out.add(x); } } int orz(){ ret=0; try { r=br.read(); } catch (IOException e) {} while(r>47&&r<58) { ret*=10; ret+=(r&15); try { r=br.read(); } catch (IOException e) {} } return ret; } } ``` --- ### d103 物流派送系統 解法:DFS ```Java= import java.util.*; import java.io.*; public class d103 implements Runnable{ public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out)); public static int ret,r,x,y,ma=0,mb=0; public static ArrayList<ArrayList<pii>> a=new ArrayList<>(); public static void main(String[] args) throws Exception{ new Thread(null,new d103(),"",1<<26).start(); } public void run() { final int n=orz(); for(int i=0;i<n;i++)a.add(new ArrayList<pii>()); for(int i=1;i<=n-1;i++) { x=orz(); y=orz(); a.get(i).add(new pii(x,y)); a.get(x).add(new pii(i,y)); } dfs(0,0,-1,0); System.out.println(ma); System.out.println(mb); } void dfs(int x,int leng,int pre,int cur) { if(leng>ma)ma=leng; if(cur>mb)mb=cur; for(pii i:a.get(x)) { if(i.x==pre)continue; dfs(i.x,leng+i.y,x,cur+1); } } int orz(){ ret=0; try { r=br.read(); } catch (IOException e) {} while(r>47&&r<58) { ret*=10; ret+=(r&15); try { r=br.read(); } catch (IOException e) {} } return ret; } } class pii{ int x,y; pii(int a,int b){ x=a; y=b; } } ``` --- ### d104 購物中心選位置 解法:樹重心 ```Java= import java.io.*; import java.util.*; public class d104 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static fa[] a=new fa[100005]; public static int[] son=new int[100005]; public static int[] node=new int[100005]; public static int ret,r,cent=-1; public static void main(String[] args) throws Exception{ final int n=orz(); final double d=n/2; int x,y; long cnt=0; fa p; a[0]=new fa(0,0,0); for(int i=1;i<=n-1;i++) { x=orz(); y=orz(); a[i]=new fa(i,x,y); son[x]++; } Queue<fa> q=new LinkedList<>(); for(int i=0;i<n;i++) { if(son[i]==0) { q.offer(a[i]); } } Arrays.fill(node,1); while(!q.isEmpty()) { p=q.poll(); if(cent==-1&&node[p.a]>=d) { cent=p.a; } if(p.a==0)continue; node[p.b]+=node[p.a]; cnt+=Math.min(node[p.a],n-node[p.a])*p.c; son[p.b]--; if(son[p.b]==0)q.offer(a[p.b]); } System.out.println(cent); System.out.println(cnt); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } class fa{ int a,b,c; fa(int x,int y,int z){ a=x; b=y; c=z; } } ``` --- ### d105 自動分裝 解法:DFS ```Java= import java.io.*; public class d105 implements Runnable{ public static int ret,r,n,m,w; public static int[] ow,nw; public static int[][] node,cw; public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out)); public static void main(String[] args) throws IOException { new Thread(null,new d105(),"",1<<26).start(); } public void run() { n=readnum(); m=readnum(); ow=new int[n]; nw=new int[m]; node=new int[n][2]; cw=new int[n][2]; for(int i=0;i<n;i++)ow[i]=readnum(); for(int i=0;i<m;i++)nw[i]=readnum(); int f; for(int i=0;i<n-1;i++) { f=readnum(); node[f][0]=readnum(); node[f][1]=readnum(); } setup(1); for(int i=0;i<m;i++) { w=nw[i]; put(1); } try { bw.flush(); } catch (IOException e) { } System.exit(0); } static int readnum() { ret=0; try { r=br.read(); } catch (IOException e) { } while(r>47&&r<58) { ret*=10; r-=48; ret+=r; try {r=br.read();} catch (IOException e) {} } return ret; } static int setup(int x) { if(x>=n) { return ow[x-n]; } cw[x][0]=setup(node[x][0]); cw[x][1]=setup(node[x][1]); return cw[x][0]+cw[x][1]; } static void put(int x) { if(x>=n) { try {bw.write(x+" ");} catch (IOException e) {} return; } if(cw[x][0]<=cw[x][1]) { cw[x][0]+=w; put(node[x][0]); } else { cw[x][1]+=w; put(node[x][1]); } } } ``` --- ### d106 寶石的顏色 解法:DFS、undo、離散化 ```Java= import java.io.*; import java.util.*; public class d106 implements Runnable{ static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); static BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out)); static HashMap<Integer,Integer> mp=new HashMap<>(); static int ret,r,max=0,cnt=0; static int[] d=new int[1000005]; static int[] num=new int[1000005]; static ArrayList<ArrayList<Integer>> e=new ArrayList<>(); public static void main(String[] args) throws Exception{ new Thread(null,new d106(),"",1<<26).start(); } public void run() { final int n=orz(); int a,b; for(int i=0;i<n;i++)e.add(new ArrayList<Integer>()); for(int i=0;i<n;i++) { d[i]=orz(); if(mp.get(d[i])==null)mp.put(d[i],cnt++); } for(int i=0;i<n-1;i++) { a=orz(); b=orz(); e.get(a).add(b); e.get(b).add(a); } dfs(0,-1); System.out.println(max); System.exit(0); } void dfs(int x,int pre) { int g=mp.get(d[x]); num[g]++; if(num[g]>max)max=num[g]; for(int i:e.get(x)) { if(i==pre)continue; dfs(i,x); } num[g]--; } int orz() { ret=0; try {r=br.read(); } catch (Exception e) {} while(r>47&&r<58) { ret*=10; ret+=(r&15); try {r=br.read(); } catch (Exception e) {} } return ret; } } ``` --- ### d107 樹的最大獨立集 解法:Greedy ```Java= import java.io.*; import java.util.*; public class d107 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int r,ret,cnt=0; public static int[] fa=new int[100005]; public static int[] so=new int[100005]; public static boolean[] t=new boolean[100005]; public static void main(String[] args) throws Exception{ final int n=orz(); int a,p; for(int i=1;i<n;i++) { a=orz(); fa[i]=a; so[a]++; } Queue<Integer> q=new LinkedList<>(); Arrays.fill(t,true); for(int i=0;i<n;i++) { if(so[i]==0)q.offer(i); } while(!q.isEmpty()) { p=q.poll(); if(t[p]) { cnt++; t[fa[p]]=false; } so[fa[p]]--; if(so[fa[p]]==0) { q.offer(fa[p]); } } System.out.println(cnt); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } class fa{ int a,b,c; fa(int x,int y,int z){ a=x; b=y; c=z; } } ``` --- ### d108 樹狀圖的距離總和 解法:遞迴 ```Java= import java.io.*; import java.util.*; public class d108 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static fa[] a=new fa[100005]; public static int[] son=new int[100005]; public static int[] node=new int[100005]; public static int ret,r; public static void main(String[] args) throws Exception{ final int n=orz(); int x; long cnt=0; fa p; a[1]=new fa(1,1,0); for(int i=2;i<=n;i++) { x=orz(); a[i]=new fa(i,x,0); son[x]++; } for(int i=2;i<=n;i++) { a[i].c=orz(); } Queue<fa> q=new LinkedList<>(); for(int i=1;i<=n;i++) { if(son[i]==0) { q.offer(a[i]); } } Arrays.fill(node,1); while(!q.isEmpty()) { p=q.poll(); if(p.a==1)continue; node[p.b]+=node[p.a]; cnt+=(((long)node[p.a]*(n-node[p.a]))*p.c)*2; son[p.b]--; if(son[p.b]==0)q.offer(a[p.b]); } System.out.println(cnt); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } class fa{ int a,b,c; fa(int x,int y,int z){ a=x; b=y; c=z; } } ``` --- ### d109 公司派對 解法:DP tree ```Java= import java.io.*; import java.util.*; public class d109 implements Runnable{ static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); static int ret,r,cnt; static ArrayList<ArrayList<Integer>> s=new ArrayList<>(); static int[] p=new int[100005]; static int[] dp0=new int[100005]; static int[] dp1=new int[100005]; public static void main(String[] args) throws Exception{ new Thread(null,new d109(),"",1<<26).start(); } public void run() { final int n=orz(); int in; p[1]=orz(); for(int i=0;i<=n;i++)s.add(new ArrayList<Integer>()); for(int i=2;i<=n;i++) { in=orz(); s.get(in).add(i); p[i]=orz(); } dfs(1); System.out.println(Math.max(dp0[1],dp1[1])); } void dfs(int x) { for(int i:s.get(x)) { dfs(i); } cnt=0; for(int i:s.get(x)) { cnt+=dp0[i]; } dp1[x]=cnt+p[x]; cnt=0; for(int i:s.get(x)) { cnt+=Math.max(dp0[i],dp1[i]); } dp0[x]=cnt; } int orz() { ret=0; try {r=br.read(); } catch (Exception e) {} while(r>47&&r<58) { ret*=10; ret+=(r&15); try {r=br.read(); } catch (Exception e) {} } return ret; } } ``` --- ### d110 不同成本的購物中心 解法:DP tree ```Java= import java.io.*; import java.util.*; public class d110 implements Runnable{ static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); static int ret,r,cnt; static ArrayList<ArrayList<Integer>> s=new ArrayList<>(); static int[] p=new int[100005]; static int[] dp0=new int[100005]; static int[] dp1=new int[100005]; static int[] dp2=new int[100005]; public static final int inf=1<<30; public static void main(String[] args) throws Exception{ new Thread(null,new d110(),"",1<<26).start(); } public void run() { int a,b; final int n=orz(); for(int i=0;i<=n;i++)s.add(new ArrayList<Integer>()); for(int i=1;i<=n;i++)p[i]=orz(); for(int i=0;i<n-1;i++) { a=orz(); b=orz(); s.get(a).add(b); s.get(b).add(a); } dfs(1,-1); System.out.println(Math.min(dp1[1],dp2[1])); } void dfs(int x,int pre) { boolean leaf=true,select; int min=1<<30; for(int i:s.get(x)) { if(i==pre)continue; dfs(i,x); leaf=false; } if(leaf) { dp0[x]=0; dp1[x]=inf; dp2[x]=p[x]; return; } cnt=0; for(int i:s.get(x)) { if(i==pre)continue; cnt+=Math.min(dp1[i],dp2[i]); } dp0[x]=cnt; cnt=0; for(int i:s.get(x)) { if(i==pre)continue; cnt+=Math.min(dp2[i],dp1[i]); min=Math.min(dp2[i]-dp1[i],min); } dp1[x]=cnt+Math.max(0,min); cnt=0; for(int i:s.get(x)) { if(i==pre)continue; cnt+=Math.min(dp0[i],Math.min(dp1[i],dp2[i])); } dp2[x]=cnt+p[x]; } int orz() { ret=0; try {r=br.read(); } catch (Exception e) {} while(r>47&&r<58) { ret*=10; ret+=(r&15); try {r=br.read(); } catch (Exception e) {} } return ret; } } ``` --- ### d111 血緣關係 解法:BFS ```Java= import java.io.*; import java.util.*; public class d111 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static ArrayList<ArrayList<Integer>> a=new ArrayList<>(); public static int ret,r,ans=-1; public static long root; public static boolean[] vis=new boolean[100005]; public static void main(String[] args) throws Exception{ final int n=orz(); int x,y,p=-1; for(int i=0;i<n;i++)a.add(new ArrayList<Integer>()); root=(n-1)*n/2; for(int i=0;i<n-1;i++) { x=orz(); y=orz(); a.get(x).add(y); a.get(y).add(x); root-=y; } Queue<Integer> q=new LinkedList<>(); q.offer((int)root); while(!q.isEmpty()) { p=q.poll(); vis[p]=true; for(int i:a.get(p)) { if(!vis[i])q.offer(i); } } q.offer(p); q.offer(-1); Arrays.fill(vis,false); while(!q.isEmpty()) { p=q.poll(); if(p==-1) { ans++; if(!q.isEmpty())q.offer(-1); continue; } vis[p]=true; for(int i:a.get(p)) { if(!vis[i])q.offer(i); } } System.out.println(ans); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d112 服務中心選位置 解法:DP ```Java= mport java.io.*; import java.util.*; public class d112 implements Runnable{ static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); static int ret,r,cnt; static ArrayList<ArrayList<Integer>> s=new ArrayList<>(); static int[] dp0=new int[100005]; static int[] dp1=new int[100005]; static int[] dp2=new int[100005]; public static final int inf=1<<30; public static void main(String[] args) throws Exception{ new Thread(null,new d112(),"",1<<26).start(); } public void run() { int a,b; final int n=orz(); for(int i=0;i<=n;i++)s.add(new ArrayList<Integer>()); for(int i=0;i<n-1;i++) { a=orz(); b=orz(); s.get(a).add(b); s.get(b).add(a); } dfs(1,-1); System.out.println(Math.min(dp1[1],dp2[1])); } void dfs(int x,int pre) { boolean leaf=true; int min=1<<30; for(int i:s.get(x)) { if(i==pre)continue; dfs(i,x); leaf=false; } if(leaf) { dp0[x]=0; dp1[x]=inf; dp2[x]=1; return; } cnt=0; for(int i:s.get(x)) { if(i==pre)continue; cnt+=Math.min(dp1[i],dp2[i]); } dp0[x]=cnt; cnt=0; for(int i:s.get(x)) { if(i==pre)continue; cnt+=Math.min(dp2[i],dp1[i]); min=Math.min(dp2[i]-dp1[i],min); } dp1[x]=cnt+Math.max(0,min); cnt=0; for(int i:s.get(x)) { if(i==pre)continue; cnt+=Math.min(dp0[i],Math.min(dp1[i],dp2[i])); } dp2[x]=cnt+1; } int orz() { ret=0; try {r=br.read(); } catch (Exception e) {} while(r>47&&r<58) { ret*=10; ret+=(r&15); try {r=br.read(); } catch (Exception e) {} } return ret; } } ``` --- ### d113 竊聽間諜網 解法:DP ```Java= import java.io.*; import java.util.*; public class d113 implements Runnable{ static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); static int ret,r,cnt; static ArrayList<ArrayList<Integer>> s=new ArrayList<>(); static int[] dp0=new int[100005]; static int[] dp1=new int[100005]; public static final int inf=1<<30; public static void main(String[] args) throws Exception{ new Thread(null,new d113(),"",1<<26).start(); } public void run() { final int n=orz(); for(int i=0;i<n;i++)s.add(new ArrayList<Integer>()); for(int i=1;i<n;i++) { s.get(orz()).add(i); } dfs(0); System.out.println(Math.min(dp0[0],dp1[0])); } void dfs(int x) { int min=1<<30; for(int i:s.get(x))dfs(i); cnt=0; for(int i:s.get(x)) { cnt+=Math.min(dp0[i],dp1[i]); } dp1[x]=cnt+1; cnt=0; for(int i:s.get(x)) { cnt+=dp1[i]; } dp0[x]=cnt; } int orz() { ret=0; try {r=br.read(); } catch (Exception e) {} while(r>47&&r<58) { ret*=10; ret+=(r&15); try {r=br.read(); } catch (Exception e) {} } return ret; } } ``` --- ### d114 佔領連續的城鎮 解法:DP ```Java= import java.io.*; import java.util.*; public class d114 implements Runnable{ static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); static int ret,r,ans=0; static ArrayList<ArrayList<Integer>> s=new ArrayList<>(); static int[] dp=new int[100005]; static int[] mp=new int[100005]; static boolean neg; public static void main(String[] args) throws Exception{ new Thread(null,new d114(),"",1<<26).start(); } public void run() { final int n=orz(); int a,b; for(int i=0;i<=n;i++)s.add(new ArrayList<Integer>()); for(int i=1;i<=n;i++)mp[i]=orz(); for(int i=1;i<n;i++) { a=orz(); b=orz(); s.get(a).add(b); s.get(b).add(a); } dfs(1,-1); System.out.println(ans); } void dfs(int x,int pre) { int cnt=0; for(int i:s.get(x)) { if(i==pre)continue; dfs(i,x); cnt+=Math.max(0,dp[i]); } dp[x]=cnt+mp[x]; ans=Math.max(dp[x],ans); } int orz() { ret=0; neg=false; re(); if(r=='-') { neg=true; re(); } while(r>47&&r<58) { ret*=10; ret+=(r&15); re(); } if(neg)ret*=-1; return ret; } void re() { try {r=br.read(); } catch (Exception e) {} } } ``` --- ### d115 樹上一位不回家的推銷員 解法:DFS ```Java= import java.io.*; import java.util.*; public class d115 implements Runnable{ static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); static int ret,r,ans=0; static ArrayList<ArrayList<edge>> s=new ArrayList<>(); static int[] d=new int[50005]; static boolean neg; public static void main(String[] args) throws Exception{ new Thread(null,new d115(),"",1<<26).start(); } public void run() { final int n=orz(); for(int i=0;i<n;i++)s.add(new ArrayList<edge>()); int a,b,c,mx=0,idx=-1; for(int i=0;i<n-1;i++) { a=orz(); b=orz(); c=orz(); ans+=(c*2); s.get(a).add(new edge(b,c)); s.get(b).add(new edge(a,c)); } dfs(0,0,-1); for(int i=0;i<n;i++) { if(d[i]>mx) { mx=d[i]; idx=i; } } dfs(idx,0,-1); for(int i=0;i<n;i++) { if(d[i]>mx) { mx=d[i]; } } System.out.println(ans-mx); } void dfs(int x,int l,int pre) { d[x]=l; for(edge i:s.get(x)) { if(i.n==pre)continue; dfs(i.n,l+i.l,x); } } int orz() { ret=0; neg=false; re(); while(r>47&&r<58) { ret*=10; ret+=(r&15); re(); } return ret; } void re() { try {r=br.read(); } catch (Exception e) {} } } class edge{ int n,l; edge(int a,int b){ n=a; l=b; } } ``` --- ### d116 病毒演化 解法:DP tree ```Java= import java.io.*; import java.util.*; public class d116 { public static ArrayList<ArrayList<Integer>> son=new ArrayList<>(); public static String[] base; public static int[][] dp; public static HashMap<Character,Integer> mp=new HashMap<>(); public static final int max=1<<30; public static void main(String[] args) throws Exception { BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); String[] in=br.readLine().split(" "); int n=Integer.parseInt(in[0]); int l=Integer.parseInt(in[1]); setup(n); int fa,sn,root=-1; for(int i=0;i<n;i++) { in=br.readLine().split(" ");//read sn=Integer.parseInt(in[0]); fa=Integer.parseInt(in[1]); base[sn]=in[2]; if(fa==sn) { root=fa;//root continue; } son.get(fa).add(sn);//加節點 } int variety=0; int min; for(int i=0;i<l;i++) { for(int k=0;k<4;k++) { dp[root][k]=max; } //initialize dfs(root,i); //dfs min=max; //find DP min for(int j=0;j<4;j++) { if(min>dp[root][j]) { min=dp[root][j]; } } variety+=min; } System.out.println(variety); } public static void dfs(int n,int x) { int id=mp.get(base[n].charAt(x));//父節點鹼基 if(son.get(n).isEmpty()) { //樹節點 if(id==4) { //@ for(int i=0;i<4;i++) { dp[n][i]=0; } } else { //A U C G dp[n][id]=0; } return; } //other node for(int i:son.get(n)) { dfs(i,x); } int id2,l,r; l=(id==4)?0:id; r=(id==4)?4:id+1; for(int j=l;j<r;j++) { dp[n][j]=0; for(int i:son.get(n)) { id2=mp.get(base[i].charAt(x));//子孫鹼基 if(id2==4){//son=@ dp[n][j]+=alpha(n,j,i); } else if(id2==j) {//same dp[n][j]+=dp[i][id2]; } else {//not the same dp[n][j]+=dp[i][id2]+1; } } } } public static void setup(int n) { //變數定義 dp=new int[n+1][4];//dp base=new String[n+1];//鹼基 mp.put('A',0);//A->0 mp.put('U',1); mp.put('C',2); mp.put('G',3); mp.put('@',4); for(int i=0;i<=n;i++)son.add(new ArrayList<Integer>()); } public static int alpha(int n,int idn,int m) { int mn=max;//找尋變異最小的子節點; for(int i=0;i<4;i++) { if(idn==i) { if(mn>dp[m][i]) { mn=dp[m][i]; } } else { if(mn>dp[m][i]+1) { mn=dp[m][i]+1; } } } return mn; } } ``` --- ### d118 山寨華山論劍 解法:sort、DP ```Java= import java.io.*; import java.util.*; public class d118 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r,max; public static void main(String[] args) throws Exception{ final int n=orz(); oq p; ac[] a=new ac[n]; for(int i=0;i<n;i++) { a[i]=new ac(orz(),orz(),orz()); } Arrays.sort(a,new Comparator<ac>() { public int compare(ac f,ac s) { return f.l-s.l; } }); PriorityQueue<oq> pq=new PriorityQueue<>(new Comparator<oq>() { public int compare(oq f,oq s) { return f.r-s.r; } }); for(int i=0;i<n;i++) { while(!pq.isEmpty()) { p=pq.poll(); if(p.r>=a[i].l) { pq.offer(p); break; } max=Math.max(p.val,max); } pq.offer(new oq(a[i].r,max+a[i].val)); } while(!pq.isEmpty()) { p=pq.poll(); max=Math.max(p.val,max); } System.out.println(max); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } class ac{ int l,r,val; ac(int x,int y,int z){ l=x; r=y; val=z; } } class oq{ int r,val; oq(int x,int y){ r=x; val=y; } } ``` ---