1005: (stupid tower defense)
From the question, we obviously know that the Red Tower is the best at the end.
Let's assume that there are j green towers and I-j blue towers in the first one. Therefore, no matter how the sequence of the first I tower is put, the impact on the subsequent tower is exactly the same.
DP [I] [J]: the greatest value of the previous I-tower with J green towers.
DP [I] [J] = max (DP [I-1] [J-1] + energy value obtained from the current tower putting the Green Tower, DP [I-1] [J] + the energy value obtained from the blue tower of the current Tower );
#include <iostream>#include<stdio.h>#include<vector>#include<queue>#include<stack>#include<string.h>#include<algorithm>using namespace std;#define LL __int64#define lcm(a,b) (a*b/gcd(a,b))LL intx(LL num,LL t,LL x,LL chi){ return num*t*(x+chi);}LL inty(LL num,LL t,LL y,LL chi){ return (t)*y*(num-1)*num/2+chi*t*num;}LL intz(LL num,LL t,LL z,LL chi){ return chi*(num*t+(num-1)*num/2*z);}LL dp[1501][1501];int main(){ LL n,x,y,z,t,cas,i,j; scanf("%I64d",&cas); LL nn = 1; while(cas--) { scanf("%I64d%I64d%I64d%I64d%I64d",&n,&x,&y,&z,&t); LL ans = t*x*n; LL sum; memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++) { dp[i][0]=dp[i-1][0]; ans=max(ans,dp[i][0]+intx(n-i,t+i*z,x,0)); for(int j=1;j<=i-1;j++) { dp[i][j]=max(dp[i-1][j-1]+inty(1,t+z*(i-j),y,(j-1)*y), dp[i-1][j]+intz(1,t+z*(i-1-j),z,j*y)); ans=max(ans,dp[i][j]+intx(n-i,t+(i-j)*z,x,j*y)); } dp[i][i]=dp[i-1][i-1]+inty(1,t,y,(i-1)*y); ans=max(ans,dp[i][i]+intx(n-i,t,x,i*y)); } printf("Case #%I64d: %I64d\n",nn++,ans); } return 0;}
1007: (magical forest)
All sorts of discretization, And Then mark the row that the row originally belongs to, then it will be done in a mess.
#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <assert.h>#include<iostream>#include<vector>using namespace std;#define MAXN 10050#define LL __int64vector<int>vecx,vecxx;vector<int>vecy,vecyy;struct list{ int x; int y; int c; friend bool operator <(const list &a,const list &b) { if(a.x!=b.x)return a.x<b.x; else return a.y<b.y; }}node[110000];int fx[110000];int fy[110000];int k;int find(int x,int leap){ // cout<<x<<" "<<leap<<endl; if(leap==0) { int l=0; int r=vecx.size(); int mid=(l+r)/2; while(l<r) { //cout<<l<<" "<<r<<" "<<mid<<" "<<vecx[mid]<<endl; if(vecx[mid]<x)l=mid+1; else r=mid; mid=(l+r)/2; } if(mid!=vecx.size()&&vecx[mid]==x)return mid+1; else return 0; } if(leap==1) { int l=0; int r=vecy.size(); int mid=(l+r)/2; while(l<r) { if(vecy[mid]<x)l=mid+1; else r=mid; mid=(l+r)/2; } if(mid!=vecy.size()&&vecy[mid]==x)return mid+1; else return 0; } return 0;}void out(int x,int y){ // cout<<x<<" -- "<<y<<endl; if(x==0||y==0) { cout<<"0"<<endl; return; } int l=1; int r=k+1; int mid=(l+r)/2; while(l<r) { if(node[mid].x<x)l=mid+1; else if(node[mid].x>x)r=mid; else if(node[mid].x==x) { if(node[mid].y<y)l=mid+1; else if(node[mid].y>=y)r=mid; } mid=(l+r)/2; } if(node[mid].y==y&&node[mid].x==x&&mid<=k) { cout<<node[mid].c<<endl; } else cout<<"0"<<endl;}int main(){ int W,cas; int n,m; scanf("%d",&W); cas=0; while(W--) { cas++; scanf("%d%d%d",&n,&m,&k); vecx.clear(); vecxx.clear(); vecy.clear(); vecyy.clear(); fx[0]=fy[0]=0; for(int i=1;i<=k;i++) { fx[i]=i; fy[i]=i; scanf("%d%d%d",&node[i].x,&node[i].y,&node[i].c); vecxx.push_back(node[i].x); vecyy.push_back(node[i].y); } sort(vecxx.begin(),vecxx.end()); sort(vecyy.begin(),vecyy.end()); vecx.push_back(vecxx[0]); vecy.push_back(vecyy[0]); for(int i=1;i<k;i++) { if(vecxx[i]!=vecxx[i-1])vecx.push_back(vecxx[i]); if(vecyy[i]!=vecyy[i-1])vecy.push_back(vecyy[i]); } for(int i=1;i<=k;i++) { node[i].x=find(node[i].x,0); node[i].y=find(node[i].y,1); } sort(node+1,node+k+1); printf("Case #%d:\n",cas); int q,x,a,b; scanf("%d",&q); while(q--) { scanf("%d%d%d",&x,&a,&b); if(x==1) { a=find(a,0); b=find(b,0); swap(fx[a],fx[b]); } if(x==2) { a=find(a,1); b=find(b,1); swap(fy[a],fy[b]); } if(x==3) { a=find(a,0); b=find(b,1); out(fx[a],fy[b]); } } } return 0;}
1010: FSF's game
We can know from the question that for any rectangle with N and m length, we can get the score:
Assume that gcd (n, m) = 2 ^ x * 3 ^ y..., and D is a factor of N.
(N, m) = N * m/(gcd (n, m) * (2 ^ 0 + 2 ^ 1 + .. + 2 ^ X) * (3 ^ 0 + 3 ^ 1 +... + 3 ^ y );
Obviously, when n is fixed, M is equal to 1 ~ When n, m/(gcd (n, m) * (2 ^ 0 + 2 ^ 1 + .. + 2 ^ X) * (3 ^ 0 + 3 ^ 1 +... + 3 ^ y) is equal to the sum of all D * (D + 1)/2.
Then we can pre-process the sum of a number factor, and then use the recursive formula directly.
#include <iostream>#include<stdio.h>#include<vector>#include<queue>#include<stack>#include<string.h>#include<algorithm>using namespace std;#define maxn 550000#define UI unsigned int#define N 550000#define LL __int64UI ans[maxn];UI use[maxn];void mk(){ memset(use,0,sizeof(use)); for(UI i=1;i<maxn;i++) { LL now=(LL)i*((LL)i+(LL)1)/(LL)2; UI add=now; for(UI j=i;j<maxn;j+=i) { use[j]=use[j]+add; } }}void init(){ mk(); ans[1]=1; for(UI i=2;i<maxn;i++) { ans[i]=ans[i-1]+use[i]*(UI)i; }}int main(){ int T,n; init(); scanf("%d",&T); int cas=0; while(T--) { cas++; scanf("%d",&n); printf("Case #%d: %u\n",cas,ans[n]); } return 0;}