Notas Tiendas de construcción

No comprender el significado de las preguntas que comienzan ...
tienda de dulces hechos a media, hay dos opciones hechas y no hechas.
Hecho ai, ans + ci, no se hace, ans + d (donde una tienda de dulces con su extremo izquierdo);
como 01 mochila. Por lo tanto, la definición de estado dp dp [i] [0] y dp [i] [. 1] representan el estado i no se hace o se hizo.
La respuesta final está en entre hacer y no toma de decisiones, (ans = min (dp [ n] [0], dp [n] [1])
para ver una gran variedad de métodos, el tiempo y estudio

  1. Método (a)
#include <iostream>
#include <algorithm>
using namespace std;
const int inf = 0x3f3f3f3f;
struct p{
//注意数据范围啊!老是被坑
 long long int x, c;
};
//给的数据没有排好序
bool cmp(p p1,p p2){
 return p1.x<p2.x;
}
int n;
//dp数组
long long dp[3001][2];
p a[3001];
int main(){
 while(cin >> n){
  memset(dp,0,sizeof(dp));
  memset(a,0,sizeof(a));
  for(int i=1;i<=n;i++){
   cin>> a[i].x >> a[i].c;
  }
  sort(a+1,a+1+n,cmp);
  //最左边一定要造一个,也就是第一个
  dp[1][1] = a[1].c; 
  //dp[ i ] [ 0 ]代表i处不建造的情况,初始化为inf:因为后面要根据dp[i -1][ 0 or 1 ]的情况推导
  dp[1][0]=inf;
  for(int i=2;i<=n;i++){
  //判断i处建造的最优解:由前一个的最优状态得到
   dp[i][1]=min(dp[i-1][0],dp[i-1][1])+ a[i].c;
   dp[i][0]=inf;
   long long sum=0;
   for(int j=i-1;j>=1;j--){
   //sum是用来计算距离总和的
   /*
   已知i处不建
   j枚举的最近糖果屋,每段都算了一次,
   比如
   j=i-1时,1*d(a[i],a[i-1]) i~i-1算了一次
   j=i-2时,2*d(a[i-1],a[i-2]) i~i-2算了一次,i-1~i-2算了一次
   依此类推,可计算得到总和 
   节省时间   一个很有意思的想法,像数列求和时用的
   s1+s2+s3+...+sn = a1*n+ a2 *(n-1) + a3*(n-2)+...+an一样的想法,不用再分别计算s1到sn的值了
   适用于排好序的情况
   */
    sum += (i-j)*(a[j+1].x - a[j].x);
    //不断更新,得到i处不建时的最优解,也就是找到最合适的j作为离它最近的糖果屋,来使cost最小
    dp[i][0]=min(dp[j][1]+sum,dp[i][0]);
  }
  }
  long long ans = min(dp[n][1],dp[n][0]);
  cout<< ans <<endl; 
  }
}
Publicado 24 artículos originales · ganado elogios 2 · Vistas 975

Supongo que te gusta

Origin blog.csdn.net/weixin_43521836/article/details/88553790
Recomendado
Clasificación