2019湖南多校第一場

 I、 Intergalactic Bidding

theme:n個人在進行拍賣,每個人的出價至少是當前最高價的兩倍,給定s,輸出出價和爲s的這些人的名字,沒有則輸出0

solution: 先將這n個人按錢數從大到小排,先找到錢數開始<=s的人,由於“每個人的出價至少是當前最高價的兩倍”,可知對於任意一個人i,他的錢比他後面人(錢數小於他)的錢數之和還大。所以要想和達到s,則這個人必須選(因爲剩下的加起來都沒i錢多,那就更<s了),所以遍歷後s-=m[i],之後重複尋找。最終s=0代表有,!=0則表示不存在組合。

由於s的是z大整數,所以考慮用java寫,注意刪掉包名,用Main命名類


import java.math.BigInteger;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

import javax.naming.ldap.SortControl;

class Participnt{
	public String name;
	public BigInteger t;
	public Participnt(String name,BigInteger t){
		this.name=name;
		this.t=t;
	}
}

public class Main {
	public static void main(String args[]){
		Scanner input=new Scanner(System.in);
		int n =input.nextInt();
		BigInteger s=input.nextBigInteger();
		Participnt participnt[] = new Participnt[n];
		String ans[]=new String[n];
		int ansnum=0;
	
		for(int i=0;i<n;++i){
			String name=input.next();
			BigInteger t=input.nextBigInteger();
			participnt[i]=new Participnt(name, t);
		}
		Arrays.sort(participnt,0,n,new MyCompare());
		
		for(int i=n-1;i>=0;--i){
			if(s.compareTo(participnt[i].t)>=0){
				s=s.subtract(participnt[i].t);
				ans[ansnum++]=new String(participnt[i].name);
			}
		}
		Arrays.sort(ans,0,ansnum);
		if(s.compareTo(BigInteger.ZERO)==0){
			System.out.println(ansnum);
			for(int i=0;i<ansnum;++i){
				System.out.println(ans[i]);				
			}
		}else
			System.out.println(0);
	}
	static class MyCompare implements Comparator<Participnt>{

		@Override
		public int compare(Participnt a, Participnt b) {
			if(a.t.compareTo(b.t)>0){
				return 1;
			}else if(a.t.compareTo(b.t)<0){
				return -1;
			}else
				return 0;
		}
		
	}
}

K、 King's Colors

theme:給定一顆n個結點的樹, 結點編號從0~n,有k種顏色,問怎麼用這k種顏色給n個結點塗色,使得k種顏色都被用上且相鄰結點(父子結點,注意不是相鄰兄弟結點)顏色不同,不同方案數有幾種?

solution:如果是最多用k種顏色,則答案是個G(k)=k(k-1)^(n-1)種,設f(k)爲恰好用k種顏色的方案數,則

由二項式反演得

extension:二項式反演

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
#define far(i,a,b) for(int i=a;i<b;++i)
#define fdr(i,a,b) for(int i=b-1;i>=a;--i)

int mod=1000000007;
ll c[2505][2505]={0};

void getC(int x)
{
    far(i,0,x+1)
    {
        c[i][0]=1;
        c[i][i+1]=0;
        for(int j=1;j<=i;++j)
        {
            c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
            //cout<<i<<" "<<j<< " "<<c[i-1][j]<<" "<<c[i-1][j-1]<<" "<<c[i][j]<<endl;
        }
    }
}

ll qm(ll x,int n)//x^n
{
    ll ans=1;
    while(n)
    {
        if(n%2)
            ans=ans*x%mod;
        x=x*x%mod;
        n>>=1;
    }
    return ans;
}

int main()
{
    getC(2500);
    int n,k;
    cin>>n>>k;
    int x;
    far(i,1,n)
        scanf("%d",&x);
    ll sum=0;
    far(i,2,k+1)
    {
        int sign=(k-i)%2 ?-1:1;
        sum=((sum+sign*c[k][i]*i%mod*qm((ll)i-1,n-1)%mod)%mod+mod)%mod;
    }
    printf("%lld",sum);
}
  • 代碼中注意的點:組合求法採用dp,c[i][j]=c[i-1][j]+c[i-1][j-1]
  • (k-1)^(n-1)用快速冪
  • 注意結果爲正,而sum在一步步加的過程中可能爲負,(a-b)%5與a%5-b%5不等!

F、Firing the Phaser

theme:給定r個邊界與x,y軸平行的矩形房間,由左下角和右上角座標表示,有一艘飛船想通過發射一束激光來一次性襲擊儘可能多的房間,激光的起點和發射角度自定,但長度l已知,問最多能一次襲擊多少個房間(交叉就代表被襲擊)

A、Altruistic Amphibians

theme:有n只青蛙掉進深度爲d的洞裏,給定這n只青蛙能跳的高度l,重量w和高度h,每次青蛙可以通過疊在比它重的青蛙的背上跳出,這個時候它能跳的高度就是h1+l2了,可以無限疊但要保證每隻青蛙的重量要>=它上面所有青蛙的重量之和。疊完後一隻跳出後下面的青蛙重回到地面重新疊。問最多有多少隻青蛙能跳出去(>d才能跳出)。

solution:按重量從大到小排序(因爲重量最大的只能靠自己,沒法踩在被動青蛙身上),然後遍歷每隻青蛙,前面的都是比他重的,此時的目的是找到滿足重量疊加條件且疊起高度最高的疊加方案,用dp[w[i]]表示重量爲w[i]的青蛙能疊起來的最大高度,則狀態轉移方程爲dp[j]=max(dp[j],h[i]+dp[w[i]+j])(for j in range[1,wi-1]),因爲如果重量爲w[i]的青蛙都能疊上去,則重量比它輕的也一定能疊在相同的青蛙上。

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
#define far(i,n) for(int i=0;i<n;++i)

struct _a
{
    int l,w,h;
}a[100010];

ll dp[100000010]={0};
int m=100000001;

bool cmp(_a x,_a y)
{
    return x.w>y.w;
}

int main()
{
    int n,d;
    cin>>n>>d;
    far(i,n)
        scanf("%d%d%d",&a[i].l,&a[i].w,&a[i].h);
    sort(a,a+n,cmp);
    int ans=0;
    far(i,n)
    {
        if(dp[a[i].w]+a[i].l>d)
            ++ans;
        for(int j=a[i].w+1;j<min(a[i].w*2,m);++j)
            dp[j-a[i].w]=max(dp[j-a[i].w],dp[j]+a[i].h);
    }
    printf("%d",ans);
}

H、House Lawn

theme:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章