[T1 蒜头君当大厨]
题解:
显然差分约束,怕你看不出样例还疯狂暗示你= =
\(code\):
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<ctype.h>
#define ll long long
using namespace std;
char buf[1<<20],*p1,*p2;
inline char gc()
{
// return getchar();
return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin))==p1?0:*p1++;
}
template<typename T>
inline void read(T &x)
{
char tt;
bool flag=0;
while(!isdigit(tt=gc())&&tt!='-');
tt=='-'?(flag=1,x=0):(x=tt-'0');
while(isdigit(tt=gc())) x=x*10+tt-'0';
if(flag) x=-x;
}
struct node{
ll x,len;
inline node(ll a=0,ll b=0)
{
x=a;
len=b;
}
inline bool operator<(node a)const
{
return len<a.len;
}
};
queue<ll>q;
vector<node>G[20005];
ll n,m,dis[20005],tot[20005];
bool book[20005];
int spfa(int s) {
for(int i=1; i<=n; i++) dis[i]=-1,book[i]=false;
dis[s]=0,q.push(s),book[s]=true,tot[s]++;
while (!q.empty()) {
ll x=q.front();
q.pop(),book[x]=false;
if(tot[x]==n+1) return -1;
for (int i=G[x].size()-1; i>=0; i--) {
ll p=G[x][i].x;
ll len=G[x][i].len;
if(dis[p]>=dis[x]+len) continue;
dis[p]=dis[x]+len;
if(book[p]) continue;
q.push(p),book[p]=true,tot[p]++;
}
}
return 1;
}
int main()
{
read(n),read(m);
for(ll i=1;i<=n;i++)
G[0].push_back(node(i,0));
for(int i=1;i<=m;i++)
{
ll op,x,y,z;
read(op);
if(op<=2) read(x),read(y),read(z);
if(op>=3) read(x),read(z);
if(op==1) G[x].push_back(node(y,z));
if(op==2) G[y].push_back(node(x,z));
if(op==3) G[0].push_back(node(x,z));
if(op==4) G[x].push_back(node(0,-z));
}
ll ans=0;
if(spfa(0)==-1) puts("I can't"),exit(0);
for(int i=1;i<=n;i++)
ans=max(ans,dis[i]);
printf("%lld",ans);
}
[T2 上课]
题解:
贪心预处理出\(g[i]\),表示能力为\(i\)时最早的时刻为多少,然后就类似背包一样的\(DP\)
\(code:\)
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<ctype.h>
#define ll long long
#define inf 1e9+9
using namespace std;
char buf[1<<20],*p1,*p2;
inline char gc()
{
// return getchar();
return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin))==p1?0:*p1++;
}
template<typename T>
inline void read(T &x)
{
char tt;
bool flag=0;
while(!isdigit(tt=gc())&&tt!='-');
tt=='-'?(flag=1,x=0):(x=tt-'0');
while(isdigit(tt=gc())) x=x*10+tt-'0';
if(flag) x=-x;
}
struct node{
int t,len,x;
inline node(int a=0,int b=0,int c=0)
{
t=a;
len=b;
x=c;
}
inline bool operator<(node a) const
{
return t<a.t;
}
}a[1005];
int t,m,n;
int f[1005],g[105];
int main()
{
read(t),read(m),read(n);
for(int i=1;i<=m+1;i++) f[i]=-inf;
for(int i=1;i<=m;i++)
{
int x,y,z;
read(x),read(y),read(z);
a[i]=node(x,y,z);
}
a[0].x=1,a[0].len=0,a[0].t=1,a[m+1].t=t+1;
sort(a+1,a+1+m);
for(int i=0;i<=100;i++) g[i]=inf;
for(int i=1;i<=n;i++)
{
int x,y;
read(x),read(y);
g[y]=min(g[y],x);
}
for(int i=1;i<=100;i++) g[i]=min(g[i],g[i-1]);
for(int i=1;i<=m+1;i++)
for(int j=0;j<i;j++)
f[i]=max(f[i],f[j]+(a[i].t-(a[j].t+a[j].len))/g[a[j].x]);
printf("%d",f[m+1]);
}
[T3 营救]
题解:
说实话思路很简单,但是但代码实现能力对我来说是硬伤啊\(......\)正解\(BFS+\)三进制状压\(DP\),略恶心
\(code:\)
#include<stdio.h>
#include<iostream>
#include<math.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<queue>
#define ll long long
#define inf 1e9+9
using namespace std;
struct point{
int x,y;
inline point(int a=0,int b=0)
{
x=a;
y=b;
}
}start,end_;
struct node{
int x,y,s;
inline node(int a=0,int b=0,int c=0)
{
x=a;
y=b;
s=c;
}
inline node(point a,int b=0)
{
x=a.x;
y=a.y;
s=b;
}
};
int n,m,k,ans=inf,tot;
int val[11];
char a[11][11],ss[11];
int f[200005][11][11];
int s[20];
queue<node>q;
int quanji;
int calspd(int num)
{
int len=0,sum=k;
memset(s,0,sizeof(s));
while(num)
{
s[++len]=num%3;
num/=3;
}
for(int i=1;i<=tot;i++)
sum+=(s[i]==1)?val[i]:0;
return sum<1?1:sum;
}
int merge(int num,int x,int y)
{
int len=0,sum=0;
memset(s,0,sizeof(s));
while(num)
{
s[++len]=num%3;
num/=3;
}
int flag=0;
for(int i=1;i<=tot;i++)
if(ss[i]==a[x][y]) flag=i;
if(s[flag]) return 0;
s[flag]=1;
for(int i=tot;i>=1;i--)
sum=sum*3+s[i];
return sum;
}
int drop1(int num)//放下减速的
{
int len=0,sum=0;
memset(s,0,sizeof(s));
while(num)
{
s[++len]=num%3;
num/=3;
}
for(int i=1;i<=tot;i++)
if(s[i]==1&&val[i]>0) s[i]=2;
for(int i=tot;i>=1;i--)
sum=sum*3+s[i];
return sum;
}
int drop2(int num)//全放下
{
int len=0,sum=0;
memset(s,0,sizeof(s));
while(num)
{
s[++len]=num%3;
num/=3;
}
for(int i=1;i<=tot;i++)
if(s[i]) s[i]=2;
for(int i=tot;i>=1;i--)
sum=sum*3+s[i];
return sum;
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
char tt;
scanf("\n%c",&tt);
if(tt=='s') start=point(i,j);
if(tt=='#') a[i][j]='#';
if(tt=='t') end_=point(i,j);
if(tt>='A'&&tt<='Z') a[i][j]=tt,tot++;
}
quanji=pow(3,tot)-1;
for(int i=1;i<=tot;i++)
{
char tt;
int x;
scanf("\n%c%d",&tt,&x);
ss[i]=tt;
val[tt-'A'+1]=x;
}
// printf("%d %d %d",drop1(3),drop2(3),merge(3,3,3));
for(int i=0;i<=quanji;i++)
for(int j=1;j<=10;j++)
for(int z=1;z<=10;z++)
f[i][j][z]=inf;
f[0][start.x][start.y]=0;
q.push(node(start,0));
while(!q.empty())
{
int tx=q.front().x,ty=q.front().y,ts=q.front().s;
q.pop();
int spd=calspd(ts);
if(tx+1<=n&&a[tx+1][ty]!='#'&&f[ts][tx+1][ty]>f[ts][tx][ty]+spd)//下
{
f[ts][tx+1][ty]=f[ts][tx][ty]+spd;
q.push(node(tx+1,ty,ts));
}
if(ty+1<=m&&a[tx][ty+1]!='#'&&f[ts][tx][ty+1]>f[ts][tx][ty]+spd)//右
{
f[ts][tx][ty+1]=f[ts][tx][ty]+spd;
q.push(node(tx,ty+1,ts));
}
if(tx-1>0&&a[tx-1][ty]!='#'&&f[ts][tx-1][ty]>f[ts][tx][ty]+spd)//上
{
f[ts][tx-1][ty]=f[ts][tx][ty]+spd;
q.push(node(tx-1,ty,ts));
}
if(ty-1>0&&a[tx][ty-1]!='#'&&f[ts][tx][ty-1]>f[ts][tx][ty]+spd)//左
{
f[ts][tx][ty-1]=f[ts][tx][ty]+spd;
q.push(node(tx,ty-1,ts));
}
if(a[tx][ty]>='A'&&a[tx][ty]<='Z')//合并
{
int newset=merge(ts,tx,ty);
if(!newset||f[newset][tx][ty]<=f[ts][tx][ty]) continue;
f[newset][tx][ty]=f[ts][tx][ty];
q.push(node(tx,ty,newset));
}
if(tx==end_.x&&ty==end_.y)//放下
{
int new1=drop1(ts),new2=drop2(ts);
if(f[new1][tx][ty]>f[ts][tx][ty])
{
f[new1][tx][ty]=f[ts][tx][ty];
q.push(node(tx,ty,new1));
}
if(f[new2][tx][ty]>f[ts][tx][ty])
{
f[new2][tx][ty]=f[ts][tx][ty];
q.push(node(tx,ty,new2));
}
}
}
printf("%d",f[quanji][end_.x][end_.y]);
}