1. 程式人生 > >dp 洛谷P1977 出租車拼車 線性dp

dp 洛谷P1977 出租車拼車 線性dp

賦值 先後 方向 準備 sam ring main pri 後來

題目背景

話說小 x 有一次去參加比賽,雖然學校離比賽地點不太遠,但小 x 還是想坐 出租車去。大學城的出租車總是比較另類,有“拼車”一說,也就是說,你一個人 坐車去,還是一堆人一起,總共需要支付的錢是一樣的(每輛出租上除司機外最 多坐下 4 個人)。剛好那天同校的一群 Oier 在校門口紮堆了,大家果斷決定拼車 去賽場。

問題來了,一輛又一輛的出租車經過,但裏面要麽坐滿了乘客,要麽只剩下 一兩個座位,眾 Oier 都覺得坐上去太虧了,小 x 也是這麽想的。

題目描述

假設 N 位 Oier 準備拼車,此時為 0 時刻,從校門到目的地需要支付給出租

車師傅 D 元(按車次算,不管裏面坐了多少 Oier),假如 S 分鐘後恰能趕上比賽,

那麽 S 分鐘後經過校門口的出租車自然可以忽略不計了。現在給出在這 S 分鐘當

中經過校門的所有的 K 輛出租車先後到達校門口的時間 T i 及裏面剩余的座位 Zi

(1 <= Zi <= 4),Oier 可以選擇上車幾個人(不能超過),當然,也可以選擇上 0 個

人,那就是不坐這輛車。

俗話說,時間就是金錢,這裏小 x 把每個 Oier 在校門等待出租車的分鐘數 等同於花了相同多的錢(例如小 x 等待了 20 分鐘,那相當於他額外花了 20 元錢)。

在保證所有 Oier 都能在比賽開始前到達比賽地點的情況下,聰明的你能計 算出他們最少需要花多少元錢麽?

輸入輸出格式

輸入格式:

每組數據以四個整數 N , K , D , S 開始,具體含義參見題目描述。

接著 K 行,表示第 i 輛出租車在第 Ti 分鐘到達校門,其空余的座位數為 Zi

(時間按照先後順序)。

N <= 100,K <= 100,D <= 100,S <= 100,1 <= Zi <= 4,1<= T(i) <= T(i+1) <= S

輸出格式:

對於每組測試數據,輸出占一行,如果他們所有人能在比賽前到達比賽地點,

則輸出一個整數,代表他們最少需要花的錢(單位:元),否則請輸出“impossible”。

輸入輸出樣例

輸入樣例#1: 復制
2 2 10 5
1 1
2 2
輸出樣例#1: 復制
14



這個是一個dp,對於dp數組的定義十分重要,開始我定義前,到第i分鐘的時候還有j人沒有上車,我覺得我定義的一塌糊塗,根本就不對,感覺沒有用腦袋思考,後來看了題解之後
就知道最好定義成前i兩個上了j個人花費的錢。
之前我自己的定義我覺得我是沒有認真在寫的,因為題目中給了兩個很明確的量,一個是車輛一個是人數,所以最好用這個來定義,開始最好從正方向去定義,因為我們一般對於
正方向比較熟練。
在這個定義完之後,還有一個轉移方程要寫,這個轉移方程要註意不能直接去轉移所有可能上去人數的,因為兩個車直接時間隔的太長了,然後又不能一次性全部上車,還不如之前可以上去,
就先上去了。
所以這個位置,轉移要註意,可以有三層循環,最內層就是對於每次上車多少人進行轉移。
然後還有就是每一個dp因為要對自己進行轉移,所以就要給她賦初值。這個初值不能亂賦,而是賦值成如果不上這輛車的話,j個人所用的費用。



#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 110;
int dp[maxn][maxn];
struct node
{
	int t, z;
}exa[maxn];
int main()
{
	int n, d, k, s;
	cin >> n >> k >> d >> s;
	for (int i = 1; i <= k; i++) scanf("%d%d", &exa[i].t, &exa[i].z);
	for (int i = 1; i <= n; i++) dp[0][i] = inf;
	dp[0][0] = 0;
	for (int i = 1; i <= k; i++)
	{
		for (int j = 0; j <= n; j++)
		{
			dp[i][j] = dp[i-1][j];
			for (int k = 1; k <= min(j, exa[i].z); k++)
			{
				dp[i][j] = min(dp[i - 1][j - k] + k * exa[i].t + d, dp[i][j]);
			}
		}
	}
	if (dp[k][n] >= inf) printf("impossible\n");
	else printf("%d\n", dp[k][n]);
	return 0;
}

  











dp 洛谷P1977 出租車拼車 線性dp