程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> TC SRM 585

TC SRM 585

編輯:C++入門知識

DIV 2 1000PT  EnclosingTriangleColorful

問有多少個三角形包含了所有的黑色的點

先是兩兩枚舉出所有點對,判斷所有的黑點是否在同一側

然後枚舉所有三角形,O(1)判斷

預處理O(m*m*n),枚舉O(m*m*m)


[cpp]
const int N = 305; 
bool upleft[N][N],upright[N][N],downleft[N][N],downright[N][N]; 
bool updown_toleft[N][N],updown_toright[N][N],leftright_toup[N][N],leftright_todown[N][N]; 
class EnclosingTriangleColorful { 
public: 
int xmul(int x0,int y0,int x1,int y1,int x2,int y2){ 
    return (x1-x0)*(y2-y0)-(x2-x0)*(y1-y0); 

int getNumber(int m, vector <int> x, vector <int> y) { 
    int n=x.size(); 
    for(int i=1;i<m;i++){ 
        for(int j=1;j<m;j++){ 
            bool f1=true,f2=true; 
            for(int k=0;k<n;k++){ 
                if(xmul(i,m,0,j,x[k],y[k])<0) 
                    f1=false; 
                if(xmul(i,m,m,j,x[k],y[k])>0) 
                    f2=false; 
            } 
            upleft[i][j]=f1;upright[i][j]=f2; 
        } 
    } 
    for(int i=1;i<m;i++){ 
        for(int j=1;j<m;j++){ 
            bool f1=true,f2=true; 
            for(int k=0;k<n;k++){ 
                if(xmul(i,0,0,j,x[k],y[k])>0) 
                    f1=false; 
                if(xmul(i,0,m,j,x[k],y[k])<0) 
                    f2=false; 
            } 
            downleft[i][j]=f1;downright[i][j]=f2; 
        } 
    } 
    for(int i=1;i<m;i++){ 
        for(int j=1;j<m;j++){ 
            bool f1=true,f2=true; 
            for(int k=0;k<n;k++){ 
                if(xmul(i,m,j,0,x[k],y[k])<0) 
                    f1=false; 
                if(xmul(i,m,j,0,x[k],y[k])>0) 
                    f2=false; 
            } 
            updown_toright[i][j]=f1;updown_toleft[i][j]=f2; 
        } 
    } 
    for(int i=1;i<m;i++){ 
        for(int j=1;j<m;j++){ 
            bool f1=true,f2=true;; 
            for(int k=0;k<n;k++){ 
                if(xmul(0,i,m,j,x[k],y[k])<0) 
                    f1=false; 
                if(xmul(0,i,m,j,x[k],y[k])>0) 
                    f2=false; 
            } 
            leftright_toup[i][j]=f1;leftright_todown[i][j]=f2; 
        } 
    } 
    int ans=0; 
    for(int i=1;i<m;i++)  //up  
        for(int j=1;j<m;j++){   //left  
            for(int k=1;k<m;k++){  //right  
                if(upleft[i][j]&&upright[i][k]&&leftright_toup[j][k]){ 
                    // cout<<i<<" "<<j<<" "<<k<<" "<<leftright[j][k]<<endl;  
                    ans++; 
                } 
            } 
        } 
    for(int i=1;i<m;i++)  //up  
        for(int j=1;j<m;j++){   //down  
            for(int k=1;k<m;k++){  //right  
                if(updown_toright[i][j]&&upright[i][k]&&downright[j][k]){ 
                    // cout<<i<<" "<<j<<" "<<k<<endl;  
                    ans++; 
                } 
            } 
        } 
    for(int i=1;i<m;i++)  //up  
        for(int j=1;j<m;j++){   //left  
            for(int k=1;k<m;k++){  //down  
                if(upleft[i][j]&&updown_toleft[i][k]&&downleft[k][j]){ 
                    // cout<<i<<" "<<j<<" "<<k<<endl;  
                    ans++; 
                } 
            } 
        } 
    for(int i=1;i<m;i++)  //down  
        for(int j=1;j<m;j++){   //left  
            for(int k=1;k<m;k++){  //right  
                if(downleft[i][j]&&downright[i][k]&&leftright_todown[j][k]){ 
                    // cout<<i<<" "<<j<<" "<<k<<endl;  
                    ans++; 
                } 
            } 
        } 
    return ans; 

 
 
}; 

const int N = 305;
bool upleft[N][N],upright[N][N],downleft[N][N],downright[N][N];
bool updown_toleft[N][N],updown_toright[N][N],leftright_toup[N][N],leftright_todown[N][N];
class EnclosingTriangleColorful {
public:
int xmul(int x0,int y0,int x1,int y1,int x2,int y2){
 return (x1-x0)*(y2-y0)-(x2-x0)*(y1-y0);
}
int getNumber(int m, vector <int> x, vector <int> y) {
 int n=x.size();
 for(int i=1;i<m;i++){
  for(int j=1;j<m;j++){
   bool f1=true,f2=true;
   for(int k=0;k<n;k++){
    if(xmul(i,m,0,j,x[k],y[k])<0)
     f1=false;
    if(xmul(i,m,m,j,x[k],y[k])>0)
     f2=false;
   }
   upleft[i][j]=f1;upright[i][j]=f2;
  }
 }
 for(int i=1;i<m;i++){
  for(int j=1;j<m;j++){
   bool f1=true,f2=true;
   for(int k=0;k<n;k++){
    if(xmul(i,0,0,j,x[k],y[k])>0)
     f1=false;
    if(xmul(i,0,m,j,x[k],y[k])<0)
     f2=false;
   }
   downleft[i][j]=f1;downright[i][j]=f2;
  }
 }
 for(int i=1;i<m;i++){
  for(int j=1;j<m;j++){
   bool f1=true,f2=true;
   for(int k=0;k<n;k++){
    if(xmul(i,m,j,0,x[k],y[k])<0)
     f1=false;
    if(xmul(i,m,j,0,x[k],y[k])>0)
     f2=false;
   }
   updown_toright[i][j]=f1;updown_toleft[i][j]=f2;
  }
 }
 for(int i=1;i<m;i++){
  for(int j=1;j<m;j++){
   bool f1=true,f2=true;;
   for(int k=0;k<n;k++){
    if(xmul(0,i,m,j,x[k],y[k])<0)
     f1=false;
    if(xmul(0,i,m,j,x[k],y[k])>0)
     f2=false;
   }
   leftright_toup[i][j]=f1;leftright_todown[i][j]=f2;
  }
 }
 int ans=0;
 for(int i=1;i<m;i++)  //up
  for(int j=1;j<m;j++){   //left
   for(int k=1;k<m;k++){  //right
    if(upleft[i][j]&&upright[i][k]&&leftright_toup[j][k]){
     // cout<<i<<" "<<j<<" "<<k<<" "<<leftright[j][k]<<endl;
     ans++;
    }
   }
  }
 for(int i=1;i<m;i++)  //up
  for(int j=1;j<m;j++){   //down
   for(int k=1;k<m;k++){  //right
    if(updown_toright[i][j]&&upright[i][k]&&downright[j][k]){
     // cout<<i<<" "<<j<<" "<<k<<endl;
     ans++;
    }
   }
  }
 for(int i=1;i<m;i++)  //up
  for(int j=1;j<m;j++){   //left
   for(int k=1;k<m;k++){  //down
    if(upleft[i][j]&&updown_toleft[i][k]&&downleft[k][j]){
     // cout<<i<<" "<<j<<" "<<k<<endl;
     ans++;
    }
   }
  }
 for(int i=1;i<m;i++)  //down
  for(int j=1;j<m;j++){   //left
   for(int k=1;k<m;k++){  //right
    if(downleft[i][j]&&downright[i][k]&&leftright_todown[j][k]){
     // cout<<i<<" "<<j<<" "<<k<<endl;
     ans++;
    }
   }
  }
 return ans;
}


};
DIV1 250 PT TrafficCongestion


一棵滿二叉樹,問有多少條不相交的路徑,遍歷所有的點

觀察奇偶的最優解,得到遞推式,兩個奇的合成偶的,無法合並原來的路徑,還得單獨考慮根,所以是兩倍加1

兩個偶的,有一條路徑可以合並,所以是兩倍減1

比賽的時候。。。沒考慮到0的情況。。。23333


[cpp]
int dp[1000005]; 
class TrafficCongestion { 
public: 
int theMinCars(int treeHeight) { 
    dp[0]=1; 
    for(int i=1;i<=treeHeight;i++) 
        if(i&1) dp[i]=(dp[i-1]*2-1)%MOD; 
    else dp[i]=(dp[i-1]*2+1)%MOD; 
    return dp[treeHeight]; 

 
 
}; 

int dp[1000005];
class TrafficCongestion {
public:
int theMinCars(int treeHeight) {
    dp[0]=1;
    for(int i=1;i<=treeHeight;i++)
     if(i&1) dp[i]=(dp[i-1]*2-1)%MOD;
    else dp[i]=(dp[i-1]*2+1)%MOD;
    return dp[treeHeight];
}


};
DIV1 500PT LISNumber

從大到小插入到序列當中,dp[i][j]表示考慮了i種數,目前LISnumber為j的數目。

那麼考慮i-1的時候,有cnt[i-1]個這樣的數。

如果新增了k個lisnumber。那麼剩下的cnt[i-1]-k個數插入進去是沒有產生lisnumber的。

只要插入點在原來的lis起點的前面,才不會新增。

也就是在原來的j個lis前面選出cnt[i-1]-k個位置,插入這些數,不產生lisnumber。

剩下的k個數,插入是要新增lisnumber的。位置包括之前的那cnt[i-1]-k個位置,序列的末端以及每個lis的中間sum-t。

這一部分轉化為k個相同的物品放入到cnt[i-1]-k+1+sum-t個不同的容器中的方案數,DP解決。


[cpp]
const int MOD = 1000000007; 
LL c[40*40][40*40]; 
LL dp[40][1300]; 
LL a[40*40][40]; 
class LISNumber { 
public: 
    LL PowMod(LL a,LL b){ 
        LL ret=1; 
        while(b){ 
            if(b&1) ret=((LL)ret*a)%MOD; 
            a=((LL)a*a)%MOD; 
            b>>=1; 
        } 
        return ret; 
    } 
    int count(vector <int> cardsnum, int K){ 
        int n=cardsnum.size(); 
        memset(dp,0,sizeof(dp)); 
        memset(a,0,sizeof(a)); 
        for(int i=1;i<=36*36;i++){ 
            c[i][0]=c[i][i]=1; 
            for(int j=1;j<i;j++) 
                c[i][j]=(c[i-1][j-1]+c[i-1][j])%MOD; 
        } 
        a[0][0]=1LL; 
        for(int i=0;i<=37*37;i++){ 
            for(int j=0;j<=37;j++){ 
                for(int k=0;k<=37&&j+k<=37;k++){ 
                    a[i+1][j+k]=(a[i+1][j+k]+a[i][j])%MOD; 
                } 
            } 
        } 
        LL sum=cardsnum[n-1]; 
        dp[n-1][cardsnum[n-1]]=1LL; 
        for(int i=n-2;i>=0;i--){ 
            for(int j=0;j<=sum&&j<=K;j++){ 
                if(dp[i+1][j]==0) continue; 
                for(int k=0;k<=cardsnum[i]&&j+k<=K;k++){ 
                    if(k+j<cardsnum[i]) continue; 
                    int t=cardsnum[i]-k; 
                    LL tmp=((LL)c[j][t]*(LL)a[t+1+(sum-j)][k])%MOD; 
                    dp[i][j+k]=(dp[i][j+k]+(LL)dp[i+1][j]*tmp)%MOD; 
                } 
            } 
            sum+=cardsnum[i]; 
        } 
        return (int)dp[0][K]; 
    } 
 
 
}; 

const int MOD = 1000000007;
LL c[40*40][40*40];
LL dp[40][1300];
LL a[40*40][40];
class LISNumber {
public:
 LL PowMod(LL a,LL b){
  LL ret=1;
  while(b){
   if(b&1) ret=((LL)ret*a)%MOD;
      a=((LL)a*a)%MOD;
   b>>=1;
  }
  return ret;
 }
 int count(vector <int> cardsnum, int K){
  int n=cardsnum.size();
  memset(dp,0,sizeof(dp));
  memset(a,0,sizeof(a));
  for(int i=1;i<=36*36;i++){
   c[i][0]=c[i][i]=1;
   for(int j=1;j<i;j++)
    c[i][j]=(c[i-1][j-1]+c[i-1][j])%MOD;
  }
  a[0][0]=1LL;
  for(int i=0;i<=37*37;i++){
   for(int j=0;j<=37;j++){
    for(int k=0;k<=37&&j+k<=37;k++){
     a[i+1][j+k]=(a[i+1][j+k]+a[i][j])%MOD;
    }
   }
  }
  LL sum=cardsnum[n-1];
  dp[n-1][cardsnum[n-1]]=1LL;
  for(int i=n-2;i>=0;i--){
   for(int j=0;j<=sum&&j<=K;j++){
    if(dp[i+1][j]==0) continue;
    for(int k=0;k<=cardsnum[i]&&j+k<=K;k++){
     if(k+j<cardsnum[i]) continue;
     int t=cardsnum[i]-k;
     LL tmp=((LL)c[j][t]*(LL)a[t+1+(sum-j)][k])%MOD;
     dp[i][j+k]=(dp[i][j+k]+(LL)dp[i+1][j]*tmp)%MOD;
    }
   }
   sum+=cardsnum[i];
  }
  return (int)dp[0][K];
 }


};

 

 


 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved