2013騰訊編程馬拉松初賽第0,1場
阿新 • • 發佈:2017-07-02
-- mat cnblogs math pen bool hid pla !=
HDU4500
直接模擬
#include <iostream> #include <cstdio> #include <cmath> #include <map> #include <algorithm> #include <cstring> #include <string> #include<set> using namespace std; #define inf 1000000007 #define MAXN 55 #define ll __int64 int z[MAXN][MAXN]; intView Codes1[4]={1,0,-1,0}; int s2[4]={0,1,0,-1}; int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF) { if(n==m&&m==0) break; memset(z,0,sizeof(z)); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) scanf("%d",&z[i][j]); }int a,b,mx; a=b=1; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { int sum=0; for(int k=0;k<4;k++) { int x,y; x=i+s1[k]; y=j+s2[k];if(z[i][j]>0) { sum=sum-z[x][y]; } else { sum=sum+z[x][y]; } } // printf("%d\n",sum); if(i==1&&j==1) mx=sum; if(sum>mx) { a=i; b=j; mx=sum; } } } printf("%d %d %d\n",a,b,mx); } return 0; }
HDU4501
0 1背包
dp[i][j][k] 代表 用掉 i 次 免費 錢為 j 積分為k 能得到的最大價值
#include <iostream> #include <cstdio> #include <cmath> #include <map> #include <algorithm> #include <cstring> #include <string> #include<set> using namespace std; #define inf 1000000007 #define MAXN 110 #define ll __int64 int dp[6][MAXN][MAXN]; struct node { int v1,v2,w; }z[MAXN]; int main() { int n,v1,v2,k; while(scanf("%d%d%d%d",&n,&v1,&v2,&k)!=EOF) { memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++) scanf("%d%d%d",&z[i].v1,&z[i].v2,&z[i].w); for(int i=1;i<=n;i++) { for(int j=v1;j>=0;j--) { for(int kk=v2;kk>=0;kk--) { for(int jj=k;jj>=0;jj--) { int now=0; if(jj>0) now=max(now,dp[jj-1][j][kk]+z[i].w); if(kk>=z[i].v2) now=max(now,dp[jj][j][kk-z[i].v2]+z[i].w); if(j>=z[i].v1) now=max(now,dp[jj][j-z[i].v1][kk]+z[i].w); dp[jj][j][kk]=max(dp[jj][j][kk],now); } } } } printf("%d\n",dp[k][v1][v2]); } return 0; }View Code
HDU4502
區間DP
dp[i][j] 代表i ~ j 天能得到的最大工資
#include <iostream> #include <cstdio> #include <cmath> #include <map> #include <algorithm> #include <cstring> #include <string> #include<set> using namespace std; #define inf 1000000007 #define MAXN 1010 #define ll __int64 int dp[110][110]; int main() { int t; scanf("%d",&t); while(t--) { int n,m; scanf("%d%d",&m,&n); memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++) { int a,b,w; scanf("%d%d%d",&a,&b,&w); dp[a][b]=max(dp[a][b],w); } for(int l=1;l<=m;l++) { for(int j=1;j<=m;j++) { int en=j+l-1; for(int k=j;k<en;k++) dp[j][en]=max(dp[j][en],dp[j][k]+dp[k+1][en]); } } printf("%d\n",dp[1][m]); } return 0; }View Code
HDU4503
考慮反面 第 i個人 調一個他的朋友 一個不是朋友
a*(n-a-1) 求和除2 就是不滿足情況的 然後總的C(n,3)
#include <iostream> #include <cstdio> #include <cmath> #include <map> #include <algorithm> #include <cstring> #include <string> #include<set> using namespace std; #define inf 1000000007 #define MAXN 1010 #define ll __int64 int dp[110][110]; int main() { int t; scanf("%d",&t); while(t--) { int n; scanf("%d",&n); int num=0; for(int i=1;i<=n;i++) { int a; scanf("%d",&a); num=num+a*(n-a-1); } num=num/2; int sum=n*(n-1)*(n-2)/6; printf("%.3lf\n",1.0*(sum-num)/sum); } return 0; }View Code
HDU4504
dp[i][j] 到第 j 次一共拿到i分
#include <iostream> #include <cstdio> #include <cmath> #include <map> #include <algorithm> #include <cstring> #include <string> #include<set> using namespace std; #define inf 1000000007 #define MAXN 1010 #define ll __int64 ll dp[1100][40]; int main() { int n,m,t; while(scanf("%d%d%d",&n,&m,&t)!=EOF) { memset(dp,0,sizeof(dp)); int a=t/15; int b=a/2; m=m+b; int ti; if(a%2==0) ti=b; else ti=b+1; dp[n][0]=1; for(int i=1;i<=ti;i++) { for(int j=n+i;j<=n+i*3;j++) { if(j-1>=0) dp[j][i]+=dp[j-1][i-1]; if(j-2>=0) dp[j][i]+=dp[j-2][i-1]; if(j-3>=0) dp[j][i]+=dp[j-3][i-1]; } } ll sum=0; for(int i=m+1;i<=n+ti*3;i++) { sum=sum+dp[i][ti]; // printf("%d %d\n",i,dp[i][ti]); } printf("%I64d\n",sum); } return 0; }View Code
HDU4505
可以一起下電梯
#include <iostream> #include <cstdio> #include <cmath> #include <map> #include <algorithm> #include <cstring> #include <string> #include<set> using namespace std; #define inf 1000000007 #define MAXN 110 #define ll __int64 int z[MAXN]; int main() { int t; scanf("%d",&t); while(t--) { memset(z,0,sizeof(z)); int n; scanf("%d",&n); for(int i=1;i<=n;i++) { int a; scanf("%d",&a); z[a]++; } int ans=0; for(int i=100;i>=1;i--) { if(z[i]) { ans=ans+10*i; break; } } for(int i=1;i<=100;i++) { if(z[i]) { ans=ans+5+z[i]; } } printf("%d\n",ans); } return 0; }View Code
HDU4506
找一下規律 就是一次向後面移一格 然後 乘以k 循環節 n
#include <iostream> #include <cstdio> #include <cmath> #include <map> #include <algorithm> #include <cstring> #include <string> #include<set> using namespace std; #define inf 1000000007 #define MAXN 10010 #define ll __int64 ll Quick(ll a,ll b,ll c) { ll ans=1; while(b) { if(b&1) ans=(ans*a)%c; b>>=1; a=(a*a)%c; } return ans; } ll z[MAXN]; int main() { int t; scanf("%d",&t); while(t--) { ll n,k,t; scanf("%I64d%I64d%I64d",&n,&t,&k); ll a=Quick(k,t,inf); ll b=t%n; for(int i=0;i<n;i++) scanf("%I64d",&z[i]); if(b==n-1) { for(int i=1;i<=n-1;i++) printf("%I64d ",(z[i]*a)%inf); printf("%I64d\n",(z[0]*a)%inf); } else { for(int i=n-b;i<n;i++) printf("%I64d ",(z[i]*a)%inf); for(int i=0;i<n-b-1;i++) printf("%I64d ",(z[i]*a)%inf); printf("%I64d\n",(z[n-b-1]*a)%inf); } } return 0; }View Code
7 數位DP 不過好像不會
HDU4508
完全背包?
#include <iostream> #include <cstdio> #include <cmath> #include <map> #include <algorithm> #include <cstring> #include <string> #include<set> using namespace std; #define inf 1000000007 #define MAXN 110 #define ll __int64 struct node { int v,co; }z[MAXN]; int dp[100010]; int main() { int n; while(scanf("%d",&n)!=EOF) { memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++) scanf("%d%d",&z[i].v,&z[i].co); int m; scanf("%d",&m); for(int i=1;i<=n;i++) { for(int j=z[i].co;j<=m;j++) { dp[j]=max(dp[j],dp[j-z[i].co]+z[i].v); } } printf("%d\n",dp[m]); } return 0; }View Code
HDU4509
排序 區間的交 線段樹麻煩了
#include <iostream> #include <cstdio> #include <cmath> #include <map> #include <algorithm> #include <cstring> #include <string> #include<set> using namespace std; #define inf 1000000007 #define MAXN 500010 #define ll __int64 struct node { int st,en; }z[MAXN]; bool cmp(node a,node b) { if(a.st==b.st) return a.en<b.en; return a.st<b.st; } int main() { int n; while(scanf("%d",&n)!=EOF) { for(int i=1;i<=n;i++) { int a,b,c,d; scanf("%d:%d %d:%d",&a,&b,&c,&d); z[i].st=a*60+b; z[i].en=c*60+d; } sort(z+1,z+n+1,cmp); int st,en; st=en=0; int sum=0; for(int i=1;i<=n;i++) { if(z[i].st>en) { sum=sum+z[i].st-en; st=z[i].st; en=z[i].en; } else if(z[i].st<=en) { en=max(en,z[i].en); } } if(en<1440) sum=sum+1440-en; printf("%d\n",sum); } return 0; }View Code
2013騰訊編程馬拉松初賽第0,1場