zoukankan      html  css  js  c++  java
  • 基础专题

    1.hdu 1028 Ignatius and the Princess III 整数划分

     1 #include<stdio.h>
     2 __int64 dp[121][121];
     3 int main()
     4 {
     5     __int64 i,j,k,n,m;
     6     for(i=0;i<=120;i++)
     7         for(j=0;j<=120;j++)
     8             dp[i][j]=0;
     9     for(i=1;i<=120;i++)
    10     {
    11         dp[i][1]=1;
    12         dp[1][i]=1;
    13     }
    14     for(i=1;i<=120;i++)
    15         for(j=1;j<=120;j++)
    16         {
    17             if(i<j)
    18                 dp[i][j]=dp[i][i];
    19             else if(i>j)
    20                 dp[i][j]=dp[i-j][j]+dp[i][j-1];
    21             else if(i==j)
    22                 dp[i][j]=1+dp[i][j-1];
    23         }
    24     while(scanf("%I64d",&n)>0)
    25     {
    26         printf("%I64d
    ",dp[n][n]);
    27     }
    28     return 0;
    29 }
    View Code

    2.hdu 1133 Buy the Ticket

    这道题,以前没有用java的时候,还没有ac。

    题意:有n个人手上有50元,m个人手上有100元。售票员手上没有零钱,所以必须要拥有50元的人先买。在任何时候,都要满足

            50的人数>=100的人数才能满足题意要求。而且,每个人是不一样的,所以针对拥有50元 或者 100 的人又是有序的。

    思路:dp[ i ] [ j ] 代表前 i  个人中,有 j 个50元的人已经买票了。

    if( j > i - j ) dp[ i ] [ j ] = dp[ i -1] [j -1 ] + dp[i - 1] [ j ]; 讨论第i 个人是50元 还是 100元。

    else dp[ i ] [ j ] = dp[ i-1 ] [ j-1 ];//此时只能由50元的人买票了.

    由于有序,所以dp[n+m][n]*c[n]*c[m]; c[ ]代表阶乘.

    //输入上要注意一下,m未必<=n,所以这样的情况,直接为0.

     1 //package mywork;
     2 
     3 import java.util.*;
     4 import java.math.BigInteger;
     5 import java.io.*;
     6 
     7 public class Main {
     8 
     9     static BigInteger c[] = new BigInteger[101];
    10     static BigInteger dp[][]= new BigInteger[202][202];
    11                                           
    12     public static void main(String[] args) {
    13         // TODO Auto-generated method stub
    14         fun();
    15         int t=1;
    16         Scanner cin  = new Scanner(System.in);
    17         while(cin.hasNext()){
    18             int n = cin.nextInt();
    19             int m = cin.nextInt();
    20             if(n==0&&m==0)break;
    21             if(m>n){
    22                 System.out.println("Test #"+t+":");
    23                 t++;
    24                 System.out.println("0");
    25                 continue;
    26             }
    27             BigInteger hxl = dp[n+m][n].multiply(c[n]).multiply(c[m]);
    28             System.out.println("Test #"+t+":");
    29             System.out.println(hxl);
    30             t++;
    31         }
    32     }
    33     static void fun(){
    34         c[0] = BigInteger.ONE;
    35         for(int i=1;i<=100;i++)
    36             c[i] = c[i-1].multiply(BigInteger.valueOf(i));
    37         
    38         for(int i=0;i<=200;i++){
    39             for(int j=0;j<=200;j++)
    40             dp[i][j] = BigInteger.ZERO;
    41         }
    42         dp[1][1]=BigInteger.ONE;
    43         for(int i=2;i<=200;i++){
    44             for(int j=1;j<=i;j++){
    45                 if(j>i-j)
    46                     dp[i][j] = dp[i-1][j].add(dp[i-1][j-1]);
    47                 else dp[i][j] = dp[i-1][j];
    48             }
    49         }
    50     }
    51 }
    View Code

    3.poj 3088 Push Botton Lock

     1 // I want to say fuck!
     2 题意: 给n个数字(1<=n<=11) ,从中选出 k 个元素,对于每一种情况,k个元素,求能分出几种集合。
     3        一个元素只能在一个集合,一个集合中的元素是无序的,集合与集合之间是有序的。
     4        这个是一种特殊的数转化过来的。
     5 思路: n中选k个就有Cn1  Cn2 Cn3 .... Cnn这些情况。
     6        对于每一种情况,求dp[i][j]代表,有i个元素,j个集合,则满足递推式
     7        dp[i][j]=j*dp[i-1][j]+dp[i-1][j-1];
     8        当然,集合与集合直接是无序的,所以最后的时候,要乘 阶乘j.(集合的个数)
     9 #include<stdio.h>
    10 typedef __int64 LL;
    11 
    12 LL dp[101][101];
    13 LL ans[13][13];
    14 LL nima[12]={1};
    15 
    16 void Init()
    17 {
    18     int i,j;
    19     for(i=1;i<=11;i++) nima[i]=nima[i-1]*i;
    20     for(i=0;i<=11;i++) ans[i][0]=1;
    21     for(i=1;i<=11;i++)
    22     {
    23         for(j=1;j<=11;j++)
    24         {
    25             if(j==1) ans[i][1]=i;
    26             else if(j==i) ans[i][i]=1;
    27             else ans[i][j]=ans[i-1][j-1]+ans[i-1][j];
    28         }
    29     }
    30     dp[1][1]=1;
    31     for(i=2;i<=100;i++)
    32         for(j=1;j<=i;j++)
    33         {
    34             dp[i][j]=j*dp[i-1][j]+dp[i-1][j-1];
    35         }
    36 }
    37 int main()
    38 {
    39     int T,i,j,n,t;
    40     LL sum,hxl;
    41     Init();
    42     scanf("%d",&T);
    43     for(t=1;t<=T;t++)
    44     {
    45         scanf("%d",&n);
    46         sum=0;
    47         for(i=1;i<=n;i++)
    48         {
    49             hxl=0;
    50             for(j=1;j<=i;j++)
    51                 hxl=hxl+dp[i][j]*nima[j];
    52             sum=sum+hxl*ans[n][i];
    53         }
    54         printf("%d %d %I64d
    ",t,n,sum);
    55     }
    56     return 0;
    57 }
    View Code

    4.poj 1496 Word Index

      1 /*写得很糟
      2   用了一个所谓的字符串哈希,发现以前神马都不管用。
      3   ar 和 bc 都是同样的hash值。(⊙o⊙)…,不想改太多,就加了了
      4   字符串判断了。
      5   其实,由于长度<=5 而且 字母不会出现相同,用二进制哈希就很好了。
      6   那么其他方法??
      7 */
      8 #include<iostream>
      9 #include<stdio.h>
     10 #include<cstring>
     11 #include<string>
     12 #include<cstdlib>
     13 using namespace std;
     14 
     15 struct node
     16 {
     17     int x;
     18     int val;
     19     char str[7];
     20     struct node *next;
     21 }f[100007];
     22 void insert(int x,int num,char c[])
     23 {
     24     int k=x%100007;
     25     node *p;
     26     p=f[k].next;
     27     while(p!=NULL && (p->x!=x ||strcmp(p->str,c)!=0))
     28     {
     29         p=p->next;
     30     }
     31     if(p==NULL)
     32     {
     33         p=(struct node*)malloc(sizeof(struct node));
     34         p->next=f[k].next;
     35         f[k].next=p;
     36         p->x=x;
     37         strcpy(p->str,c);
     38         p->val=num;
     39     }
     40 }
     41 int found(int x,char c[])
     42 {
     43     int k=x%100007;
     44     node *p;
     45     p=f[k].next;
     46     while(p!=NULL && (p->x!=x || strcmp(p->str,c)!=0) )
     47     {
     48         p=p->next;
     49     }
     50     if(p!=NULL) return p->val;
     51     return 0;
     52 }
     53 unsigned int ELFHash(char *str)
     54 {
     55     unsigned int hash = 0;
     56     unsigned int x = 0;
     57     while (*str)
     58     {
     59         hash = (hash << 4) + (*str++);
     60         if ((x = hash & 0xF0000000L) != 0)
     61         {
     62             hash ^= (x >> 24);
     63             hash &= ~x;
     64         }
     65     }
     66     return (hash & 0x7FFFFFFF);
     67 }
     68 void Init()
     69 {
     70     int i,j,s,t,k,tom=0,hxl;
     71     for(i=0;i<100007;i++)
     72     {
     73         f[i].next=NULL;
     74         f[i].val=f[i].x=0;
     75         f[i].str[0]='';
     76     }
     77     char A='a'-1;
     78     char b[10];
     79     for(i=1;i<=26;i++)
     80     {
     81         b[0]=i+A;
     82         b[1]='';
     83         hxl=ELFHash(b);
     84         ++tom;
     85         insert(hxl,tom,b);
     86     }//one
     87     for(i=1;i<=26;i++)
     88     {
     89         for(j=i+1;j<=26;j++)
     90         {
     91             b[0]=A+i;
     92             b[1]=A+j;
     93             b[2]='';
     94             hxl=ELFHash(b);
     95             ++tom;
     96             insert(hxl,tom,b);
     97         }
     98     }//two
     99     for(i=1;i<=26;i++)
    100         for(j=i+1;j<=26;j++)
    101             for(k=j+1;k<=26;k++)
    102             {
    103                 b[0]=A+i;
    104                 b[1]=A+j;
    105                 b[2]=A+k;
    106                 b[3]='';
    107                 hxl=ELFHash(b);
    108                 ++tom;
    109                 insert(hxl,tom,b);
    110             }//three
    111     for(i=1;i<=26;i++)
    112     {
    113         for(j=i+1;j<=26;j++)
    114         {
    115             for(k=j+1;k<=26;k++)
    116             {
    117                 for(s=k+1;s<=26;s++)
    118                 {
    119                     b[0]=i+A;
    120                     b[1]=j+A;
    121                     b[2]=k+A;
    122                     b[3]=s+A;
    123                     b[4]='';
    124                     hxl=ELFHash(b);
    125                     ++tom;
    126                     insert(hxl,tom,b);
    127                 }
    128             }
    129         }
    130     }//four
    131     for(i=1;i<=26;i++)
    132     {
    133         for(j=i+1;j<=26;j++)
    134         {
    135             for(k=j+1;k<=26;k++)
    136             {
    137                 for(s=k+1;s<=26;s++)
    138                 {
    139                     for(t=s+1;t<=26;t++)
    140                     {
    141                         b[0]=i+A;
    142                         b[1]=j+A;
    143                         b[2]=k+A;
    144                         b[3]=s+A;
    145                         b[4]=t+A;
    146                         b[5]='';
    147                         hxl=ELFHash(b);
    148                         ++tom;
    149                         insert(hxl,tom,b);
    150                     }
    151                 }
    152             }
    153         }
    154     }//five
    155 
    156 }
    157 int main()
    158 {
    159     Init();
    160     bool flag;
    161     char a[10];
    162     int i,j,k;
    163     while(scanf("%s",a)>0){
    164         k=strlen(a);
    165         flag=false;
    166         for(i=0;i<k;i++)
    167         {
    168             for(j=i+1;j<k;j++)
    169                 if(a[i]>=a[j])flag=true;
    170         }
    171         if(flag==true){
    172             printf("0
    ");
    173             continue;
    174         }
    175         k=ELFHash(a);
    176         k=found(k,a);
    177         printf("%d
    ",k);
    178     }
    179     return 0;
    180 }
    View Code

    5.poj 1942 Paths on a Grid Cn+m n

     1 #include<stdio.h>
     2 typedef __int64 LL;
     3 
     4 int main()
     5 {
     6     LL n,m,k,sum,i,j;
     7     while(scanf("%I64d%I64d",&n,&m)>0)
     8     {
     9         if(n==0&&m==0)break;
    10         k=n+m;
    11         if(n>m) n=m;
    12         sum=1;
    13         for(i=1,j=k;i<=n;i++,j--)
    14             sum=sum*j/i;
    15         printf("%I64d
    ",sum);
    16 
    17     }
    18     return 0;
    19 }
    View Code

    6.fzu 2020 组合

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<cstring>
     4 #include<cstdlib>
     5 using namespace std;
     6 typedef long long LL;
     7 
     8 LL pow_mod(LL a,LL b,LL p)
     9 {
    10     LL ans=1;
    11     while(b)
    12     {
    13         if(b&1) ans=(ans*a)%p;
    14         b=b>>1;
    15         a=(a*a)%p;
    16     }
    17     return ans;
    18 }
    19 LL C(LL a,LL b,LL p){
    20     if(a<b) return 0;
    21     if(b>a-b) b=a-b;
    22     LL i,sum1=1,sum2=1;
    23     for(i=0;i<b;i++){
    24         sum1=(sum1*(a-i))%p;
    25         sum2=(sum2*(b-i))%p;
    26     }
    27     return (sum1*pow_mod(sum2,p-2,p))%p;
    28 }
    29 LL Lucas(LL n,LL m,LL p)
    30 {
    31     LL ans=1;
    32     while(n&&m&&ans)
    33     {
    34         ans=(ans*C(n%p,m%p,p))%p;
    35         n=n/p;
    36         m=m/p;
    37     }
    38     return ans%p;
    39 }
    40 int main()
    41 {
    42     int T;
    43     scanf("%d",&T);
    44     while(T--){
    45         LL n,m,p;
    46         scanf("%lld%lld%lld",&n,&m,&p);
    47         if(p==1){
    48             printf("0
    ");
    49             continue;
    50         }
    51         printf("%lld
    ",Lucas(n,m,p));
    52     }
    53     return 0;
    54 }
    View Code
     1 /**
     2  题意:C(n,m)%p;  (1<=m<=n<=10^9 ,m<=10^4,m<p<10^9);
     3 
     4  Lucas定理的运用。
     5  Lucas(n,m,p)=C(n%p,m%p)%p*Lucas(n/p,m/p,p); p为素数.
     6  
     7  {
     8  纠正一个错误
     9  for(i=1,j=n;i<=m;i++,j--)
    10  sum=(sum*j/i)%p;
    11  如果没有取模和溢出的条件下,这样做是可以的。
    12  但是,取模就不对啦。例子C(10,4)%107。
    13  }
    14  后来知道,用了一个叫做乘法逆元的东东。
    15 【定义】若整数a,b,p, 满足a·b≡1(mod p).则称a 为b 模p 的乘法逆元, 即a=b- 1mod p.其中, p 是模数。
    16  乘法逆元有解的前提是gcd(b,p)=1;由于题意p为素数,那就肯定成立了.
    17  应用到组合数中来就是:
    18  a!/[b!*(a-b)!] % p == a! * [b!*(a-b)!]-1 %p 
    19  ???
    20  
    21 **/
    22 #include<iostream>
    23 #include<stdio.h>
    24 #include<cstring>
    25 #include<cstdlib>
    26 using namespace std;
    27 typedef long long LL;
    28 
    29 LL pow_mod(LL a,LL n,LL p)
    30 {
    31     LL ans=1;
    32     while(n)
    33     {
    34         if(n&1) ans=(ans*a)%p;
    35         n=n>>1;
    36         a=(a*a)%p;
    37     }
    38     return ans;
    39 }
    40 void solve(LL n,LL m,LL p)
    41 {
    42     LL i,sum1=1,sum2=1;
    43     for(i=0;i<m;i++)
    44     {
    45         sum1=(sum1*(n-i))%p;
    46         sum2=(sum2*(m-i))%p;
    47     }
    48     LL ans=(sum1*pow_mod(sum2,p-2,p))%p;
    49     printf("%lld
    ",ans);
    50 }
    51 int main()
    52 {
    53     int T;
    54     LL n,m,p;
    55     scanf("%d",&T);
    56     while(T--){
    57     scanf("%lld%lld%lld",&n,&m,&p);
    58     n=n%p;
    59     if(p==1){
    60         printf("0
    ");
    61         continue;
    62     }
    63     solve(n,m,p);
    64     }
    65     return 0;
    66 }
    View Code
  • 相关阅读:
    ios 关闭自动修正输入内容
    Tarjan+缩点【强连通分量】【模板】
    初识Tarjan算法
    【尺取法】【转】
    【先加后减拼凑思想】【合成数问题】
    强连通分量【k 算法、t 算法】
    大数【加减乘除】
    洛谷博客地址【置顶!】
    差分约束+spfa【模板】
    【poj3169】【差分约束+spfa】
  • 原文地址:https://www.cnblogs.com/tom987690183/p/3680256.html
Copyright © 2011-2022 走看看