2 10 3 2 2 2 8 2 5 1 10 4 1 2 2 8 2 5 1 0 10000
18 26
题意:在圆环形的路上,某些地方xi有不定量的苹果ai,某人手里有最多能装k个苹果的篮子,取满还得回到原点 问:至少走多远
看到这个题,可能是贪心或是稍难的思维题?贪心的题解没看懂 dp明白了,特别特别像之前林大oj的周赛 987孙大神的面试 对于本题而言 所走的最短长度无非是顺时针+逆时针的
和的最小值,就这点特别像最长山峰序列有木有!反正就是顺着推一遍,逆着推一遍 最后找最小
#include <iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; typedef long long LL; struct nod { LL x,a; bool operator <(const nod &z) const { return x<z.x; } }in[100005];//这里少写了个0 WA了一次 LL dp[2][100005]; LL l,n,k,sum; LL x[100005],a[100005]; void init() { memset(dp,0,sizeof(dp)); sum=0; } void solve() { dp[0][0]=dp[1][0]=0; LL num=1,pre; for(int i=0;i<n;i++) { for(int j=0;j<a[i];j++) { pre=num-k>0?num-k:0; dp[0][num]=dp[0][pre]+(2*x[i]>l?l:2*x[i]); num++; } } num=1; for(int i=n-1;i>=0;i--) { for(int j=0;j<a[i];j++) { pre=num-k>0?num-k:0; dp[1][num]=dp[1][pre]+(2*l-2*x[i]>l?l:2*l-2*x[i]); num++; } } LL res=0x3f3f3f3f3f3f3f3f; for(int i=0;i<=sum;i++) res=min(res,dp[0][i]+dp[1][sum-i]); printf("%I64d\n",res); } int main() { freopen("cin.txt","r",stdin); int cas; scanf("%d",&cas); while(cas--) { init(); scanf("%I64d%I64d%I64d",&l,&n,&k); for(int i=0;i<n;i++) scanf("%I64d%I64d",&in[i].x,&in[i].a); sort(in,in+n); for(int i=0;i<n;i++) { x[i]=in[i].x; a[i]=in[i].a; sum+=a[i]; } solve(); } }