校赛酱油记~~~
1001(hdu5948 Thickest Burger )
src:http://acm.hdu.edu.cn/showproblem.php?pid=5948
#include <iostream> #include<cstdlib> #include<algorithm> #include<cmath> #include<functional> #include<utility> #include<string> #include<string.h> #include<vector> using namespace std; int main() { int cas,a,b; cin>>cas; while(cas--){ cin>>a>>b; if(a>b){ cout<<a*2+b<<endl; } else cout<<b*2+a<<endl; } return 0; }
1002(hdu5982 Relic Discovery)
src:http://acm.hdu.edu.cn/showproblem.php?pid=5982
#include <iostream> #include<cstdlib> #include<algorithm> #include<cmath> #include<functional> #include<utility> #include<string> #include<string.h> #include<vector> using namespace std; int main() { int cas,a,b,t; cin>>cas; while(cas--){ int ans=0; cin>>t; while(t--){ cin>>a>>b; ans+=a*b; } cout<<ans<<endl; } return 0; }
1003(hdu 1171 Big Event in HDU)
src:http://acm.hdu.edu.cn/showproblem.php?pid=1171
这题有个诡异的八阿哥,就是以负数作为结束,而不只是-1,然后这是一道多重背包问题,总价值尽可能平均分两部分,小的那部分就是小于等于sum/2,所以取背包容量就是总价值的一半。这题拆成01背包也能暴力过,评测姬结果是01背包967ms,用多重背包写是109ms.
01背包
#include <iostream> #include<cstdlib> #include<algorithm> #include<cmath> #include<functional> #include<utility> #include<string> #include<string.h> #include<vector> using namespace std; #define FOR(i,a,b) for(int i=a;i<=b;i++) int n,half,sum,ans,ad; int v[55],num[55],dp[2500000]; int main() { std::ios::sync_with_stdio(false); while(cin>>n&&n>=0){ cnt=0; half=sum=ans=0; FOR(i,1,n){ cin>>v[i]>>num[i]; sum+=v[i]*num[i]; } half=sum/2; memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++){ for(int j=1;j<=num[i];j++){ for(int k=v[i];k<=half;k++){ dp[k]=max(dp[k],dp[k-v[i]]+v[i]); } } } ans=dp[half]; int tmp=sum-ans; cout<<tmp<<' '<<ans<<endl; } return 0; }
多重背包 //使用滚动数组时一定要从大的状态滚起,这样才能保证前面的状态是上一个阶段的!!!
#include <iostream> #include<cstdlib> #include<algorithm> #include<cmath> #include<functional> #include<utility> #include<string> #include<string.h> #include<vector> using namespace std; #define FOR(i,a,b) for(int i=a;i<=b;i++) int n,half,sum,ans,ad; int v[55],num[55],dp[2500000]; int val[600],cnt; int main() { std::ios::sync_with_stdio(false); while(cin>>n&&n>=0){ cnt=0; half=sum=ans=0; FOR(i,1,n){ cin>>v[i]>>num[i]; sum+=v[i]*num[i]; } half=sum/2; memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++){ for(int j=1;num[i]>0;j*=2){ int x=min(j,num[i]); val[cnt++]=v[i]*j; num[i]-=x; } } for(int i=0;i<cnt;i++){ for(int k=half;k>=val[i];k--){//使用滚动数组时一定要从大的状态滚起,这样才能保证前面的状态是上一个阶段的!!! dp[k]=max(dp[k],dp[k-val[i]]+val[i]); } } ans=dp[half]; int tmp=sum-ans; cout<<tmp<<' '<<ans<<endl; } return 0; }
1004(hdu2952Counting Sheep)
src:http://acm.hdu.edu.cn/showproblem.php?pid=2952
#include <iostream> #include<cstdlib> #include<algorithm> #include<cmath> #include<functional> #include<utility> #include<string> #include<string.h> #include<vector> using namespace std; #define FOR(i,a,b) for(int i=a;i<=b;i++) int cas,m,n; char mp[101][101]; bool vis[101][101]; int dx[4]={-1,1,0,0}; int dy[4]={0,0,-1,1}; bool ck(int i,int j) { if(i<1||i>n||j<1||j>m)return false; return true; } void dfs(int i,int j) { vis[i][j]=true; int ti,tj; for(int t=0;t<4;t++){ ti=i+dx[t];tj=j+dy[t]; //cout<<"t "<<ti<<' '<<tj<<endl;// if(ck(ti,tj)&&mp[ti][tj]=='#'&&!vis[ti][tj]) dfs(ti,tj); } } int main() { std::ios::sync_with_stdio(false); cin>>cas; while(cas--){ cin>>n>>m; int ans=0; memset(vis,false,sizeof(vis)); FOR(i,1,n)FOR(j,1,m)cin>>mp[i][j]; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(!vis[i][j]&&mp[i][j]=='#'){ ans++; dfs(i,j); } } } cout<<ans<<endl; } return 0; }
1005(hdu4432Sum of divisors)
src:http://acm.hdu.edu.cn/showproblem.php?pid=4432
注意n==1的时候不要加多了~~~
#include <iostream> #include<cstdlib> #include<algorithm> #include<cmath> #include<functional> #include<utility> #include<string> #include<string.h> #include<vector> using namespace std; #define FOR(i,a,b) for(int i=a;i<=b;i++) int n,base; int v[10000],cnt; class baba { public: int b[100]; int ct; baba(){memset(b,0,sizeof(b));ct=1;} void init(){memset(b,0,sizeof(b));ct=1;} }tmp; void dec_to_base(int u) { while(u){ tmp.b[tmp.ct++]=u%base; u/=base; } } int main() { std::ios::sync_with_stdio(false); while(cin>>n>>base&&n&&base){ cnt=2;v[1]=1; int ans=0; for(int i=2;i<sqrt(n);i++){ if(n%i==0)v[cnt++]=i; } if(n!=1){ int tt=cnt; for(int i=1;i<tt;i++)v[cnt++]=n/v[i]; int ha=sqrt(n); if(ha*ha==n)v[cnt++]=ha; } for(int i=1;i<cnt;i++){ tmp.init(); dec_to_base(v[i]); for(int j=1;j<tmp.ct;j++){ ans+=tmp.b[j]*tmp.b[j]; } } tmp.init(); dec_to_base(ans); for(int i=tmp.ct-1;i>=1;i--){ if(tmp.b[i]>9)cout<<(char)('A'+(tmp.b[i]-10)); else cout<<tmp.b[i]; } cout<<endl; } return 0; }
1006(hdu5984 Pocky)
src : http://acm.hdu.edu.cn/showproblem.php?pid=5984
题解:https://www.cnblogs.com/cmmdc/p/7747760.html
1007(hdu5978To begin or not to begin)src http://acm.hdu.edu.cn/showproblem.php?pid=5978
水水的概率题
#include <iostream> #include<cstdlib> #include<algorithm> #include<cmath> #include<functional> #include<utility> #include<string> #include<string.h> #include<vector> using namespace std; #define FOR(i,a,b) for(int i=a;i<=b;i++) int n,half,sum,ans,ad; int v[55],num[55],dp[2500000]; int main() { int n; while(cin>>n){ n++; if(n%2==1)cout<<"1"<<endl; else cout<<"0"<<endl; } return 0; }
1008(hdu6247 这题贴的网上写的最简洁的代码~~~)
src:http://acm.hdu.edu.cn/showproblem.php?pid=6247
#include<bits/stdc++.h> using namespace std; int main() { int T,ca=0; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); int s=0; for(int i=1;i<=n;i++) { int x; scanf("%d",&x); s+=x+x/10+(x%10!=0); } printf("Case #%d: %d\n",++ca,s); } return 0; }
1009(hdu6188Duizi and Shunzi)
src:http://acm.hdu.edu.cn/showproblem.php?pid=6188
贪心,优先考虑对子,然后顺子;
对于某个对子,假设能用来组成顺子,则是aab(b)c(c)形式(a在前中后都行),1️⃣如果bc的数量都是2则abc凑对子有三个,凑顺子2个,此时凑对子好;2️⃣如果bc不是都有两个,则凑成的对子和顺子一样多;所以对于a,先凑对子肯定不亏;然后如果还有剩下来,则称剩下来的为“弃子”,把它尽可能用掉就好,此时分析下一个,如果下一个也有这种弃子,则下下个直接拿来凑成顺子,因为就算下下个能组成对子,拿来消耗掉前两个弃子也不亏,反之如果下下个也有弃子就赚了呦~~~完结!!!
ac代码:
#include <iostream> #include<cstdlib> #include<algorithm> #include<cmath> #include<functional> #include<utility> #include<string> #include<string.h> #include<vector> using namespace std; #define FOR(i,a,b) for(int i=a;i<=b;i++) const int N=1000000+50; int v[1000050],n,d; int main() { std::ios::sync_with_stdio(false); while(cin>>n){ memset(v,0,sizeof(v)); for(int i=1;i<=n;i++){ cin>>d; v[d]++; } int ans=0; for(int i=1;i<=n;i++){ ans+=v[i]/2; v[i]%=2; if(v[i]&&v[i+1]%2&&v[i+2]){ ans++; v[i]--;v[i+1]--;v[i+2]--; } } cout<<ans<<endl; } return 0; }
1010 (hdu3249Selecting Frames)
src:http://acm.hdu.edu.cn/showproblem.php?pid=3249
题意:给你N个线段,每个线段有一个自己pole,要选择尽量多的线段。
如果dp解的话,状态转移方程:dp[top]=min( dp[top] , a[i].p>=dp[top-1]+a[i].l?a[i].p:dp[top-1]+a[i].l); 可以看出,当前状态的最优解是由上一状态的最优解得来的,因此退成贪心解即可!!!

ac代码:
#include <iostream> #include<cstdlib> #include<algorithm> #include<cmath> #include<functional> #include<utility> #include<string> #include<string.h> #include<vector> using namespace std; #define FOR(i,a,b) for(int i=a;i<=b;i++) int Max(int a,int b){return a>b?a:b;} const int inf=9999999; struct frame { int len,p; }fm[100005]; int n,old,nw;//old表示前一个最小右界,nw表示新的最小右界 bool cmp(frame f1,frame f2) { if(f1.p==f2.p)return f1.len<f2.len; return f1.p<f2.p; } int main() { std::ios::sync_with_stdio(false); while(cin>>n&&n){ FOR(i,1,n)cin>>fm[i].len>>fm[i].p; sort(fm+1,fm+1+n,cmp); int sum=1; old=fm[1].p;nw=fm[1].p; for(int i=2;i<=n;i++){ if(fm[i].p>=nw){ sum++; old=nw; nw=Max(fm[i].p,old+fm[i].len); continue; } int tmp=max(fm[i].p,old+fm[i].len); if(tmp<nw)nw=tmp; } cout<<sum<<endl; } return 0; }

浙公网安备 33010602011771号