地址见 BZOJ 2748~2750
Description 一个吉他手准备参加一场演出。他不喜欢在演出时始终使用同一个音量,所以他决定每一首歌之前他都要改变一次音量。在演出开始之前,他已经做好了一个列表,里面写着在每首歌开始之前他想要改变的音量是多少。每一次改变音量,他可以选择调高也可以调低。 音量用一个整数描述。输入文件中给定整数beginLevel,代表吉他刚开始的音量,以及整数maxLevel,代表吉他的最大音量。音量不能小于0也不能大于maxLevel。输入文件中还给定了n个整数c1,c2,c3…..cn,表示在第i首歌开始之前吉他手想要改变的音量是多少。 吉他手想以最大的音量演奏最后一首歌,你的任务是找到这个最大音量是多少。 Input 第一行依次为三个整数:n, beginLevel, maxlevel。 第二行依次为n个整数:c1,c2,c3…..cn。 Output 输出演奏最后一首歌的最大音量。如果吉他手无法避免音量低于0或者高于maxLevel,输出-1。 Sample Input 3 5 10 5 3 7 Sample Output 10 HINT 1<=N<=50,1<=Ci<=Maxlevel 1<=maxlevel<=1000 0<=beginlevel<=maxlevel
很水的dp,f[i][j]表示第i首曲子j这个音量是否可以构成
1 /************************************************************** 2 Problem: 2748 3 User: zhangzjd 4 Language: C++ 5 Result: Accepted 6 Time:0 ms 7 Memory:1472 kb 8 ****************************************************************/ 9 10 #include<cstdio> 11 #include<cstdlib> 12 #include<iostream> 13 #include<algorithm> 14 using namespace std; 15 #define For(i,n) for(int i=1;i<=n;i++) 16 #define Rep(i,l,r) for(int i=l;i<=r;i++) 17 18 int A[51],F[51][1001],N,BEGIN,MAX,ans=0; 19 20 int main() 21 { 22 scanf("%d%d%d",&N,&BEGIN,&MAX); 23 For(i,N) scanf("%d",&A[i]); 24 F[0][BEGIN]=1; 25 For(i,N) 26 { 27 Rep(j,0,MAX) 28 if(F[i-1][j]){ 29 if(j+A[i]<=MAX) F[i][j+A[i]]=1; 30 if(j-A[i]>=0) F[i][j-A[i]]=1; 31 } 32 } 33 For(i,MAX) 34 if(F[N][i]) ans=max(i,ans); 35 if(ans==0) if(!F[N][0]) ans=-1; 36 cout<<ans<<endl; 37 return 0; 38 }
============================================逗比的分割线1==========================================
[HAOI2012]外星人
Time Limit: 3 Sec Memory Limit: 128 MBDescription
Input
Output
输出test行,每行一个整数,表示答案。
Sample Input
1
2
2 2
3 1
2
2 2
3 1
Sample Output
3
HINT
Test<=50 Pi<=10^5,1<=Q1<=10^9
注意到一个数n被phi之后,每个质因子都会-1,2就被减没了。也就是说如果可以算出每个质因子需要消掉多少2,就可以算出总数。
设f[i]表示i最后会分解出多少个2,那么对于质数,f[i]=f[i-1],否则 f[i*prime[j]] = f[i]+f[prime[j]]。
但是这样对于13这个数据似乎不对? 因为13这个奇数刚开始没有2,所以第一次phi没有算上,最后的ans+1即可
1 #include<set> 2 #include<queue> 3 #include<cmath> 4 #include<cstdio> 5 #include<cstdlib> 6 #include<cstring> 7 #include<iostream> 8 #include<algorithm> 9 using namespace std; 10 typedef long long ll; 11 const int N = 100010; 12 #define mp make_pair 13 #define Mod 1000000007 14 #define point pair<int,int> 15 #define For(i,n) for(int i=1;i<=n;i++) 16 #define Rep(i,l,r) for(int i=l;i<=r;i++) 17 #define Down(i,r,l) for(int i=r;i>=l;i--) 18 bool check[N]; 19 int n,x,y,prime[N],tot,tests; 20 long long ans,f[N]; 21 22 void PHI(int n){ 23 f[1] = 1; 24 for(int i=2;i<=n;i++){ 25 if(!check[i]){ 26 prime[++tot] = i; 27 f[i]=f[i-1]; 28 } 29 for(int j=1;j<=tot;j++){ 30 if(prime[j]*i>n) break; 31 check[prime[j]*i] = true; 32 f[i*prime[j]] = f[i] + f[prime[j]]; 33 if(i%prime[j]==0) break; 34 } 35 } 36 } 37 38 int main(){ 39 PHI(N-10); 40 scanf("%d",&tests); 41 while(tests--){ 42 scanf("%d",&n); 43 bool flag=false; 44 For(i,n){ 45 scanf("%d%d",&x,&y); 46 if(x==2) flag=true; 47 ans=ans+(long long)(f[x]*y); 48 } 49 if(!flag) ans++; 50 printf("%lld ",ans);ans=0; 51 } 52 return 0; 53 }
===========================================逗比的分割线2==========================================
Description C国有n座城市,城市之间通过m条单向道路连接。一条路径被称为最短路,当且仅当不存在从它的起点到终点的另外一条路径总长度比它小。两条最短路不同,当且仅当它们包含的道路序列不同。我们需要对每条道路的重要性进行评估,评估方式为计算有多少条不同的最短路经过该道路。现在,这个任务交给了你。 Input 第一行包含两个正整数n、m 接下来m行每行包含三个正整数u、v、w,表示有一条从u到v长度为w的道路 Output 输出应有m行,第i行包含一个数,代表经过第i条道路的最短路的数目对1000000007取模后的结果 Sample Input 4 4 1 2 5 2 3 5 3 4 5 1 4 8 Sample Output 2 3 2 1 HINT 数据规模 30%的数据满足:n≤15、m≤30 60%的数据满足:n≤300、m≤1000 100%的数据满足:n≤1500、m≤5000、w≤10000 Source
dijkstra+heap。用dijkstra是因为如果按dijk算法更新最短路径,那么每次选择的最小的点保存下来即是一个拓扑序,记录从起点到每个点得经过多少条最短路,以及从末尾到每个点的最短路数目,乘法原理即可。
1 #include<set> 2 #include<queue> 3 #include<cmath> 4 #include<cstdio> 5 #include<cstdlib> 6 #include<cstring> 7 #include<iostream> 8 #include<algorithm> 9 const int N=5010; 10 const int M=5010*2; 11 using namespace std; 12 typedef long long ll; 13 #define mp make_pair 14 #define Mod 1000000007 15 #define point pair<int,int> 16 #define For(i,n) for(int i=1;i<=n;i++) 17 #define Rep(i,l,r) for(int i=l;i<=r;i++) 18 #define Down(i,r,l) for(int i=r;i>=l;i--) 19 20 struct Edge{ 21 int t,w; 22 int next; 23 }E[M]; 24 bool vis[N]; 25 int Es,head[N],dis[N]; 26 int n,m,rank[N]; 27 long long ans[N],Left[M],Right[M]; 28 29 void Dijk(int s){ 30 priority_queue< point,vector<point>,greater<point> > q; 31 q.push(mp(0,s));rank[0]=0; 32 memset(dis,0x777777f,sizeof(dis));dis[s]=0; 33 memset(vis,false,sizeof(vis));memset(Left,0,sizeof(Left)); 34 while(!q.empty()){ 35 int heads=q.top().second;q.pop(); 36 if(!vis[heads]) { 37 rank[++rank[0]]=heads; 38 vis[heads]=true; 39 } 40 for(int p=head[heads];p!=-1;p=E[p].next) 41 if(dis[heads]<dis[E[p].t]-E[p].w){ 42 dis[E[p].t]=dis[heads]+E[p].w; 43 q.push(mp(dis[E[p].t],E[p].t)); 44 } 45 } 46 Left[rank[1]]=1; 47 memset(Right,0,sizeof(Right)); 48 For(i,rank[0]) Right[rank[i]]=1; 49 For(i,rank[0]) 50 for(int p=head[rank[i]];p!=-1;p=E[p].next) 51 if(dis[E[p].t]==dis[rank[i]]+E[p].w) 52 Left[E[p].t]=(Left[E[p].t]+Left[rank[i]])%Mod; 53 Down(i,rank[0],1) 54 for(int p=head[rank[i]];p!=-1;p=E[p].next) 55 if(dis[E[p].t]==dis[rank[i]]+E[p].w) 56 Right[rank[i]]=(Right[rank[i]]+Right[E[p].t])%Mod; 57 For(i,n) 58 for(int p=head[i];p!=-1;p=E[p].next) 59 if(dis[E[p].t]==dis[i]+E[p].w) 60 ans[p]=(ans[p]+(long long)Left[i]*Right[E[p].t])%Mod; 61 } 62 63 void Makelist(int s,int t,int w){ 64 E[Es].t=t;E[Es].w=w;E[Es].next=head[s]; 65 head[s]=Es++; 66 } 67 68 void read(int &v){ 69 char ch=getchar();int num=0; 70 while(ch>'9'||ch<'0') ch=getchar(); 71 while(ch>='0'&&ch<='9'){ 72 num=num*10+ch-'0'; 73 ch=getchar(); 74 }v=num; 75 } 76 77 int main(){ 78 freopen("road.in","r",stdin); 79 freopen("road.out","w",stdout); 80 read(n);read(m);int x,y,w; 81 memset(head,-1,sizeof(head)); 82 For(i,m){ 83 read(x);read(y);read(w); 84 Makelist(x,y,w); 85 } 86 For(i,n) Dijk(i); 87 Rep(i,0,m-1) printf("%lld ",ans[i]); 88 return 0; 89 }