zoukankan      html  css  js  c++  java
  • 第 46 届 ICPC 国际大学生程序设计竞赛亚洲区域赛(上海)【I:线性DP】

    直接贪心就行
     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 #define int long long
     6 
     7 const int N = 3e5+100 ,inf = 0x3f3f3f3f;
     8 
     9 int n,arr[N],k;
    10 signed  main(){
    11     cin>>n>>k;
    12     for(int i=1;i<=n;i++) cin>>arr[i];
    13     sort(arr+1,arr+1+n);
    14     int last=-inf,s=0;
    15     for(int i=1;i<=n;i++){
    16         if(arr[i]-last>=k){
    17             last=arr[i];
    18             s++;
    19         }
    20     }
    21     cout<<s;
    22     return 0;
    23 }

    通分,求解2元1次方程。小模拟一下
     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 #define int long long
     6 
     7 const int N = 3e5+100 ,inf = 0x3f3f3f3f;
     8 int p,q;
     9 
    10 signed  main(){
    11     int T=1;
    12     cin>>T;
    13     while(T--){    
    14         cin>>p>>q;
    15         int B=(2*q+p)*q;
    16         int x=(2*q+p);//x=a+b B=a*b==> a=x-b, b*b-xb+B=0
    17         int del=x*x-4*B;
    18         //cout<<del<<endl;
    19         if(del<0||(del!=((int)(sqrt(del)))*((int)(sqrt(del))))){
    20             cout<<"0 0"<<endl;
    21             continue;
    22         }
    23         int sd=sqrt(del);
    24         int b1=0,b2=0;
    25         if((x+sd)%2){
    26             b1=-1;
    27         }else{
    28             b1=(x+sd)/2;
    29         }
    30         if((x-sd)<1||(x-sd)%2){
    31             b2=-1;
    32         }else{
    33             b2=(x-sd)/2;
    34         }
    35         int a1=x-b1,a2=x-b2;
    36         if(a1>=1&&b1>=1){
    37             int t=__gcd(a1,b1);
    38             cout<<a1/t<<" "<<b1/t<<endl;
    39         }else if(a2>=1&&b2>=1){
    40             int t=__gcd(a2,b2);
    41             cout<<a2<<" "<<b2<<endl;
    42         }else{
    43             cout<<"0 0"<<endl;
    44         }
    45     }
    46     return 0;
    47 }

    从下往上考虑。并把边转换为点看(感觉会更容易点)具体看代码
     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 #define int long long
     6 #define pb push_back
     7 
     8 const int N = 2e5+100 ,inf = 0x3f3f3f3f ,mod = 998244353;
     9 
    10 //*******************Slove
    11 int n;
    12 vector<int> g[N];
    13 int p[N]; 
    14 int sz[N];
    15 int slove(int num){
    16     int s=1;
    17     for(int i=num-1;i>=1;i-=2){
    18         s%=mod,s=s*i,s%=mod;
    19     } 
    20     return s;
    21 }
    22 int ans=1;
    23 int dfs(int u,int fa){
    24     int sum=0;    
    25     for(int i=0;i<g[u].size();i++){
    26         int to=g[u][i];
    27         if(to==fa) continue;
    28         sum+=dfs(to,u);    
    29         
    30     }
    31     if(sum%2){
    32         ans=(ans*(slove(sum-1)*sum%mod))%mod;
    33     
    34         return 0;
    35     }else{
    36         ans=(ans*slove(sum))%mod;
    37         return 1;
    38     }
    39 }
    40 signed  main(){ 
    41 ans=1;
    42     cin>>n;
    43     int aa,bb;
    44     for(int i=1;i<n;i++){    
    45         scanf("%lld%lld",&aa,&bb);
    46         g[aa].pb(bb),g[bb].pb(aa);
    47     }
    48     dfs(1,0);
    49     cout<<ans<<endl;
    50     return 0;
    51 }
    52 /* */

    这题可以用用动态规划解决,因为当前状态跟上一个状态有关。假设DP(a,b,c)表示当前已经处理到第a位,用了b个功能(功能:*2的功能),且SET(S)-SET(T)的差值为c 。
    转移方程大致为:
    dp[a][b][c]=max(dp[a-1][b][c-t[i]]+v[i],dp[a][b][c]);
    dp[a][b][c]=max(dp[a-1][b][c+t[i]]+v[i],dp[a][b][c]);
    dp[a][b][c]=max(dp[a-1][b-1][c-2*t[i]],dp[a][b][c]);
    dp[a][b][c]=max(dp[a-1][b-1][c+2*t[i]],dp[a][b][c]);
    最后的ANS:max(ans,dp[~][k][~])
    注意转移的写法!
     1 //dp[a][b][c]:表示已经处理到第a位,当前用了dou b个元素,且差值为c。
     2 #include<bits/stdc++.h>
     3 using namespace std;
     4 #define int long long
     5 const int N = 109 , inf  = 1e14 , M = 2700;//M:表示当前的原点位置,基准位置 
     6 int n,k;
     7 int v[N],t[N];
     8 int dp[N][N][M*2+100];
     9 signed main(){
    10     cin>>n>>k;
    11     for(int i=1;i<=n;i++) scanf("%lld%lld",&v[i],&t[i]);
    12     for(int a=0;a<=n;a++){
    13         for(int b=0;b<=101;b++){
    14             for(int c=0;c<=2*M;c++)
    15                  dp[a][b][c]=-inf;
    16         }
    17     }
    18     dp[0][0][M]=0;
    19 
    20     for(int a=1;a<=n;a++){
    21         for(int b=0;b<=min(a,k);b++){
    22             for(int c=0;c<=2*M;c++){
    23                 dp[a][b][c]=max(dp[a-1][b][c],dp[a][b][c]);
    24                 if(c-t[a]>=0)    dp[a][b][c]=max(dp[a-1][b][c-t[a]]+v[a],dp[a][b][c]);
    25                 if(c+t[a]<=2*M)  dp[a][b][c]=max(dp[a-1][b][c+t[a]]+v[a],dp[a][b][c]);
    26                 if(b-1>=0&&c-2*t[a]>=0) dp[a][b][c]=max(dp[a-1][b-1][c-2*t[a]]+v[a],dp[a][b][c]);
    27                 if(b-1>=0&&c+2*t[a]<=2*M) dp[a][b][c]=max(dp[a-1][b-1][c+2*t[a]]+v[a],dp[a][b][c]);
    28             }
    29         }
    30     }
    31     int ans=0;
    32     for(int i=1;i<=n;i++){
    33         for(int j=0;j<=min(i,k);j++)
    34             ans=max(ans,dp[i][j][M]);
    35     }
    36     cout<<ans;
    37     return 0;
    38 }
    39 /*
    40 dp[a][b][c]=max(dp[a-1][b][c-t[i]]+v[i],dp[a][b][c]);
    41 dp[a][b][c]=max(dp[a-1][b][c+t[i]]+v[i],dp[a][b][c]);
    42 dp[a][b][c]=max(dp[a-1][b-1][c-2*t[i]],dp[a][b][c]);
    43 dp[a][b][c]=max(dp[a-1][b-1][c+2*t[i]],dp[a][b][c]);
    44 
    45 ans=max(ans,dp[n][k][~]);
    46 */
  • 相关阅读:
    Bootstrap Thumbnail
    Bootstrap Edit 使用方法
    Bootstrap Button 使用方法
    ANDROID-BOOTSTRAP开源项目使用方法
    在Android程序中使用Modbus协议时报 java.net.SocketException: recvfrom failed: ECONNRESET解决办法
    C# const 和readonly
    js之navigator对象
    C#系统学习(第三、四课变量)
    C#系统学习(第二课编译、进制的转换)
    C#系统学习(第一课初认C#)
  • 原文地址:https://www.cnblogs.com/pengge666/p/15618887.html
Copyright © 2011-2022 走看看