题意:
一个机器人要去关路灯,起初机器人站在某个位置,给出每盏路灯的位置和每秒的花费,机器人的速度是1m/s,现在问机器人在将全部灯关掉的期间,灯的最小消耗是多少。
题解:
区间dp,dp[l][r][2]表示区间l-r都关完灯了,0表示站在左边,1表示站在右边。用记忆搜索比较好些,但是边界条件要处理好。
两种方法:
#include<iostream> #include<math.h> #include<stdio.h> #include<algorithm> #include<string.h> #include<vector> #include<queue> #include<map> #include<set> #define B(x) (1<<(x)) using namespace std; typedef long long ll; void cmax(int& a,int b){ if(b>a)a=b; } void cmin(int& a,int b){ if(b<a)a=b; } void cmax(ll& a,ll b){ if(b>a)a=b; } void cmin(ll& a,ll b){ if(b<a)a=b; } void add(int& a,int b,int mod){ a=(a+b)%mod; } void add(ll& a,ll b,ll mod){ a=(a+b)%mod; } const int oo=0x3f3f3f3f; const int MOD=2012; const int maxn=1005; const int maxm=23336666; int dp[maxn][maxn][2]; int D[maxn],W[maxn]; int sum,n; int dfs(int l,int r,int pos){ if(dp[l][r][pos]!=-1)return dp[l][r][pos]; if(l==1&&r==n)return dp[l][r][pos]=0; if(pos==0){ dp[l][r][0]=min( l-1>=1?dfs(l-1,r,0)+(D[l]-D[l-1])*(sum-W[r]+W[l-1]):oo, r+1<=n?dfs(l,r+1,1)+(D[r+1]-D[l])*(sum-W[r]+W[l-1]):oo ); }else{ dp[l][r][1]=min( l-1>=1?dfs(l-1,r,0)+(D[r]-D[l-1])*(sum-W[r]+W[l-1]):oo, r+1<=n?dfs(l,r+1,1)+(D[r+1]-D[r])*(sum-W[r]+W[l-1]):oo ); } return dp[l][r][pos]; } int main(){ //freopen("E:\\read.txt","r",stdin); int v; while(scanf("%d%d",&n,&v)!=EOF){ sum=0; for(int i=1;i<=n;i++){ scanf("%d%d",&D[i],&W[i]); sum+=W[i]; W[i]+=W[i-1]; } memset(dp,-1,sizeof dp); int ans=min(dfs(v,v,0),dfs(v,v,1)); printf("%d\n",ans); } return 0; } /* 4 3 2 2 5 8 6 1 8 7 5 3 0 5 2 1 3 2 6 10 10 4 */
#include<iostream> #include<math.h> #include<stdio.h> #include<algorithm> #include<string.h> #include<vector> #include<queue> #include<map> #include<set> #include<stack> #define B(x) (1<<(x)) using namespace std; typedef long long ll; void cmax(int &a,int b){ if(b>a)a=b; } void cmin(int &a,int b){ if(b<a)a=b; } void cmax(ll &a,ll b){ if(b>a)a=b; } void cmin(ll &a,ll b){ if(b<a)a=b; } void add(int &a,int b,int mod){ a=(a+b)%mod; } void add(ll &a,ll b,ll mod){ a=(a+b)%mod; } void add(int &a,int b){ a+=b; } void add(ll &a,ll b){ a+=b; } const int oo=0x3f3f3f3f; const ll MOD=1000000007; const int maxn=1005; int dp[maxn][maxn][2]; int D[maxn],W[maxn]; int main(){ int n,v,sum; while(scanf("%d%d",&n,&v)!=EOF){ sum=0; for(int i=1;i<=n;i++){ scanf("%d%d",&D[i],&W[i]); sum+=W[i]; W[i]+=W[i-1]; } memset(dp,0x3f,sizeof dp); dp[v][v][0]=dp[v][v][1]=0; for(int i=v-1;i>=0;i--){ cmin(dp[i][v][0],dp[i+1][v][0]+(D[i+1]-D[i])*(sum-W[v]+W[i])); cmin(dp[i][v][1],dp[i][v][0]+(D[v]-D[i])*(sum-W[v]+W[i-1])); } for(int j=v+1;j<=n;j++){ cmin(dp[v][j][1],dp[v][j-1][1]+(D[j]-D[j-1])*(sum-W[j-1]+W[v-1])); cmin(dp[v][j][0],dp[v][j][1]+(D[j]-D[v])*(sum-W[j]+W[v-1])); } for(int i=v-1;i>=1;i--){ for(int j=v+1;j<=n;j++){ dp[i][j][0]=min( dp[i+1][j][0]+(D[i+1]-D[i])*(sum-W[j]+W[i]), dp[i+1][j][1]+(D[j]-D[i])*(sum-W[j]+W[i]) ); dp[i][j][1]=min( dp[i][j-1][1]+(D[j]-D[j-1])*(sum-W[j-1]+W[i-1]), dp[i][j-1][0]+(D[j]-D[i])*(sum-W[j-1]+W[i-1]) ); } } printf("%d\n",min(dp[1][n][0],dp[1][n][1])); } return 0; }