發下試題,看了一遍三個題:
T1 sb題、裸的揹包
T2 我能夠模擬。。
T3 sb題、貪心、優先隊列ios
提供一個揹包,它最多能負載重量爲W的物品。
如今給出N種物品:對於第i類物品,一共有Ci件物品;對於每一件物品,重量爲Wi,價值爲Vi。
找出一種裝載方式使得揹包中的物品總價值最大。git
第一行兩個整數N,W,表明物品的種類與揹包的總負重。
第2~N+1行,每行三個整數Wi, Vi, Ci,表明第i種物品的重量、價值與數量。優化
僅一行,一個整數V,表明最大的總價值。spa
3 9
5 8 2
3 6 2
2 1 5code
14隊列
1<=N<=20, 0<=W<=1000
1<=Wi<=100, 0<=Vi<=100, 0<=Ci<=100遊戲
我是真的服我本身,好好的多重揹包不寫,恰恰要逞能,寫個多重轉01揹包,得個5分讓本身樂呵樂呵???(我是**嘛??)ci
AC代碼:get
#include<iostream> #include<cstdio> using namespace std; int N,W; #define MAXN 1111 int w[MAXN],v[MAXN],c[MAXN]; inline int read() { int x=0,f=1; char c=getchar(); for(; !isdigit(c); c=getchar()) if(c=='-') f=-1; for(; isdigit(c); c=getchar()) x=x*10+c-'0'; return x*f; } int f[MAXN]; int main() { freopen("backpack.in","r",stdin); freopen("backpack.out","w",stdout); cin>>N>>W; for(int i=1; i<=N; i++) cin>>w[i]>>v[i]>>c[i]; for(int i=1; i<=N; i++) for(int j=1; j<=c[i]; j++) for(int k=W; k>=w[i]; k--) f[k]=max(f[k],f[k-w[i]]+v[i]); cout<<f[W]; return 0; }
Alice與Bob在玩遊戲:
Alice首先給出兩個數X與Y(X<=Y);
Bob則按順序將X,X+1,X+2,…,Y-1,Y寫成一個大數S。
Alice最後將S首尾相連,讓其圍成一個圈。
這時,Bob想知道,從S的開頭出發,日後的第L位到第R位數字之和是多少。string
第一行四個整數X,Y,L,R,表明Alice的兩個數字和Bob想要知道的第L位到第R位的數字之和。
僅一行,一個整數M,表明第L位到第R位的數字之和。
10 11 4 12
7
Bob將數字寫成一行大數S = 1011;圍成一個圈後,從第4位到第12位分別是1,1,0,1,1,1,0,1,1,它們的和是7.
對於50%的數據,L=1, X,Y,L,R<=1000;
對於100%的數據,S的長度不大於10000,X,Y,L,R<=100000000.
考試的時候,蹦出來的第一個思路是**模擬(記錄+建環),看了眼數據範圍,以爲很騷,可是又沒有想到更好的,因而……
Code:(碼風鬼畜)
#include<iostream> #include<cstdio> using namespace std; #define N 100000011 char S[N]; int X,Y,L,R; inline int read() { int x=0,f=1; char c=getchar(); for(; !isdigit(c); c=getchar()) if(c=='-') f=-1; for(; isdigit(c); c=getchar()) x=x*10+c-'0'; return x*f; } int cnt=0; int ans=0; int main(void) { freopen("circulate.in","r",stdin); freopen("circulate.out","w",stdout); X=read(); Y=read(); L=read(); R=read(); for(int i=X; i<=Y; i++) { if((i/10)==0) { S[cnt++]=(char)i; } else if((i/10<10) && (i/10>0)) { S[cnt++]=(char)(i/10); S[cnt++]=(char)(i%10); } else if((i/100<10) && (i/100>0)) { S[cnt++]=(char)(i/100); S[cnt++]=(char)(i%100/10); S[cnt++]=(char)(i%10); } else if((i/1000<10) && (i/1000>0)) { S[cnt++]=(char)(i/1000); S[cnt++]=(char)(i%1000/100); S[cnt++]=(char)(i%100/10); S[cnt++]=(char)(i%10); } else if((i/10000<10) && (i/10000>0)) { S[cnt++]=(char)(i/10000); S[cnt++]=(char)(i%10000/1000); S[cnt++]=(char)(i%1000/100); S[cnt++]=(char)(i%100/10); S[cnt++]=(char)(i%10); } else if((i/100000<10) && (i/100000>0)) { S[cnt++]=(char)(i/100000); S[cnt++]=(char)(i%100000/10000); S[cnt++]=(char)(i%10000/1000); S[cnt++]=(char)(i%1000/100); S[cnt++]=(char)(i%100/10); S[cnt++]=(char)(i%10); } else if((i/1000000<10) && (i/1000000>0)) { S[cnt++]=(char)(i/1000000); S[cnt++]=(char)(i%1000000/100000); S[cnt++]=(char)(i%100000/10000); S[cnt++]=(char)(i%10000/1000); S[cnt++]=(char)(i%1000/100); S[cnt++]=(char)(i%100/10); S[cnt++]=(char)(i%10); } else if((i/10000000<10) && (i/10000000>0)) { S[cnt++]=(char)(i/10000000); S[cnt++]=(char)(i%10000000/1000000); S[cnt++]=(char)(i%1000000/100000); S[cnt++]=(char)(i%100000/10000); S[cnt++]=(char)(i%10000/1000); S[cnt++]=(char)(i%1000/100); S[cnt++]=(char)(i%100/10); S[cnt++]=(char)(i%10); } else if((i/100000000<10) && (i/100000000>0)) { S[cnt++]=(char)(i/100000000); S[cnt++]=(char)(i%100000000/10000000); S[cnt++]=(char)(i%10000000/1000000); S[cnt++]=(char)(i%1000000/100000); S[cnt++]=(char)(i%100000/10000); S[cnt++]=(char)(i%10000/1000); S[cnt++]=(char)(i%1000/100); S[cnt++]=(char)(i%100/10); S[cnt++]=(char)(i%10); } } int opt=cnt-1; for(int i=0; i<cnt; i++) { S[++opt]=S[i]; }//2 for(int i=0; i<2*cnt; i++) { S[++opt]=S[i]; }//4 for(int i=0; i<4*cnt; i++) { S[++opt]=S[i]; }//8 for(int i=0; i<8*cnt; i++) { S[++opt]=S[i]; }//16 for(int i=0; i<16*cnt; i++) { S[++opt]=S[i]; }//32 for(int i=0; i<32*cnt; i++) { S[++opt]=S[i]; }//64 for(int i=0; i<64*cnt; i++) { S[++opt]=S[i]; }//128 for(int i=0; i<128*cnt; i++) { S[++opt]=S[i]; }//256 for(int i=0; i<256*cnt; i++) { S[++opt]=S[i]; }//512 for(int i=0; i<512*cnt; i++) { S[++opt]=S[i]; }//1024 for(int i=L-1; i<R; i++) { ans+=(int)S[i]; } cout<<ans; /* for(int i=2*opt;i>=opt+1;i--){ S[i]= }*/ /* for(int i=1; i<=cnt; i++) cout<<(int)S[i]<<"\n";*/ return 0; }
不過考試的時候,看見坐在我旁邊的cgp Dalao一直在咳咳(面露微笑)。闊怕闊怕~隱隱約約還聽到他突然叫了一句:我想到優化了!!(果真,我太菜了)
AC代碼:
#include<iostream> #include<stack> #include<cstdio> #include<cstring> using namespace std; #define N 100011 #define LL long long int stack<int>S; int a[N]; int cnt=0; LL x,y,l,r,k; LL ans=0,sum=0; int main(void) { freopen("circulate.in","r",stdin); freopen("circulate.out","w",stdout); cin>>x>>y>>l>>r; while(x<=y) { k=x; while(k!=0) { S.push(k%10); k=k/10; } while(!S.empty()) { cnt++; a[cnt]=S.top(); S.pop(); } x++; } int flag=0; sum=1; for(int i=1; i<=cnt+1; i++) { if(i==cnt+1) i=1; if(sum==l) { flag=1; } if(flag) ans+=a[i]; sum++; if(sum==r+1) break; } cout<<ans; return 0; }
Cindy和Dan在玩一個遊戲。
一開始Cindy想出了N個數,接着她把這N個數所有給了Dan。
Dan獲得這組數後,它會挑出3個數(若是不足3個則所有挑出)。Dan會把這幾個數加起來變成一個數,而後再把這個數與剩下的數再放到一塊兒。Dan會一直這樣作,直到最後只剩下一個數。
Cindy則會在旁邊記下每次Dan獲得的數,她把這些數加起來,做爲本次遊戲的得分。她想知道,對於一組數,Dan能獲得的最大的得分是多少?
第一行一個正整數N,表明這組數的個數;
第二行N個正整數,表明這N個整數。
一行一個整數,表明可能的最大得分。
4
3 1 5 6
29
Dan能夠首先把(3,5,6)這三個數先合併起來,獲得3 + 5 +6 = 14;接着他把剩下的兩個數再合起來,獲得1+14=15.這樣,總得分是最大的 14 + 15 = 29.
對於50%的數據,N<=10
對於100%的數據,N<=1000,全部數不大於1000
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> using namespace std; #define N 1111 int n; int a[N]; int ans=0; int opt=0; int main(void) { freopen("merge.in","r",stdin); freopen("merge.out","w",stdout); priority_queue<int> Q;//大頭堆 cin>>n; for(int i=1; i<=n; i++) { cin>>a[i]; Q.push(a[i]); } if(n<=3) { for(int i=1; i<=n; i++) ans+=a[i]; cout<<ans; return 0; } else { ans+=Q.top(); Q.pop();//1 ans+=Q.top(); Q.pop();//2 ans+=Q.top(); Q.pop();//3 Q.push(ans); int uxv=0; while(Q.size()>3) { for(int i=1; i<=3; i++) { uxv+=Q.top(); Q.pop(); } ans+=uxv; Q.push(uxv); uxv=0; } uxv=0; if(Q.size()<=3) { while(!Q.empty()) { uxv+=Q.top(); Q.pop(); } ans+=uxv; } cout<<ans; return 0; } }
綜合而言:此次考試我真的**了。