2018年10月30日提高組 T2 B
阿新 • • 發佈:2018-12-18
大意
一個長度為的數軸,有種移動方式,切換移動方式需要花費的代價,第種方法花費的代價使你移動格,然後有個限制,即不能用號移動方式經過第格,求最小代價。
思路
這是一種最優化問題,考慮或,本人用的是
設表示前個格子,目前使用第種移動方式,得到當之前移動方式相同時
當移動方式不同時
邊界,當時
程式碼
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;int n,k,w,f[501][101],qg[101],dj[101],xz,ans=0x3f3f3f3f,a,b;
bool cant[101][501];
inline int read()
{
char c;int f=0,d=1;
while(c=getchar(),c<48||c>57)if(c=='-')d=-1;f=(f<<3)+(f<<1)+c-48;
while(c=getchar(),c>47&&c<58) f=(f<<3)+(f<<1)+c-48;
return d*f;
}
signed main()
{
memset(f,0x3f3f3f3f,sizeof(f));
n=read();k=read();w=read();
for(register int i=1;i<=k;i++) qg[i]=read(),dj[i]=read();
xz=read();
while(xz--)
{
a=read();b=read();
for(register int i=a;i<=min(a+qg[b],n);i++) cant[b][i]=true;
}
memset(f[0],0,sizeof(f[0]));
for(register int i=1;i<=n;i++)
for(register int j=1;j<=k;j++)
{
if(cant[j][i]) continue;
if(i<qg[j]) continue;
if(i==qg[j]) f[i][j]=min(dj[j],f[i][j]);
f[i][j]=min(f[i-qg[j]][j]+dj[j],f[i][j]);//動態轉移
for(register int l=1;l<=k;l++)
if(l!=j) f[i][j]=min(f[i-qg[j]][l]+dj[j]+w,f[i][j]);//動態轉移
}
for(register int i=1;i<=k;i++) ans=min(ans,f[n][i]);//取最優解
if(ans<502345678) printf("%d",ans);
else puts("-1");
}