Tetrahedron dp
大一的时候好像看过这题,当时不会做,现在来看就是如此简单,,,
dp[i][j]代表第i步是在j点(j=A,B,C,D),所以状态方程也很好写,但是1e7会爆内存,我们考虑这个题只需要第i个状态和第i-1个状态,所以我们可以设一个滚动数组来记录状态就可以了;
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod=1e9+7;
const ll inf=0x3f3f3f3f;
ll qpow(ll a,ll b){
ll res=1;
while(b){
if(b&1) res=(res*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return res;
}
ll getinv(ll a){return qpow(a,mod-2);}
ll n,dp[2][4];
int main(){
//freopen("in.txt","r",stdin);
scanf("%lld",&n);
dp[0][0]=1;
for(int i=1;i<=n;i++){
dp[i%2][1]=((dp[(i-1)%2][0]+dp[(i-1)%2][2])%mod+dp[(i-1)%2][3])%mod;
dp[i%2][2]=((dp[(i-1)%2][0]+dp[(i-1)%2][1])%mod+dp[(i-1)%2][3])%mod;
dp[i%2][3]=((dp[(i-1)%2][0]+dp[(i-1)%2][1])%mod+dp[(i-1)%2][2])%mod;
dp[i%2][0]=((dp[(i-1)%2][1]+dp[(i-1)%2][2])%mod+dp[(i-1)%2][3])%mod;
}
printf("%lld\n",dp[n%2][0]%mod);
return 0;
}
Decrease the Sum of Digits
贪心的想改变的位数越低越好,那我们尽可能的不去改变高位,每次遍历都从高位向低位累加,加到第i位大于s了就去改变第i+1位,让第i+1位的数加1,感觉这题还是考验的代码能力;
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod=1e9+7;
const ll inf=0x3f3f3f3f;
ll qpow(ll a,ll b){
ll res=1;
while(b){
if(b&1) res=(res*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return res;
}
ll getinv(ll a){return qpow(a,mod-2);}
ll t,n,tar;
bool check(string s){
ll res=0;
for(int i=0;i<s.size();i++)
res+=(s[i]-'0');
return res<=tar;
}
ll str_num(string s){
ll res=0;
for(int i=0;i<s.size();i++)
res=res*10+(s[i]-'0');
return res;
}
int main(){
//freopen("in.txt","r",stdin);
scanf("%lld",&t);
while(t--){
scanf("%lld%lld",&n,&tar);
ll ans=0;
string s=to_string(n);
while(!check(s)){
ll res=0,ma=0;
for(int i=0;i<s.size();i++){
res+=(s[i]-'0');
if(res>tar){ma=i-1;break;}
}
if(ma==-1){
ll bef=str_num(s);
ll tm=pow(10,s.size());
ans+=tm-bef;
s=to_string(tm);
continue;
}
string s1=s.substr(ma);
ll tm=s1[0]-'0';
tm++;
tm*=pow(10,s1.size()-1);
ll bef=str_num(s1);
ans+=tm-bef;
s=s.substr(0,ma)+to_string(tm);
}
printf("%lld\n",ans);
}
return 0;
}
Happy Morse Code dp
明明之前还做过类似的题目,但一开始没有读到串最长是5,到最后还把情况考虑复杂了,真是不应该;最长是5那么第二层循环最多也就是五次,第一层循环i到n,第二层循环j到5,看看从[i-j+1,i]这个子串有没有出现过,出现过就dp[i]=dp[i]+dp[i-j]*mp[zichuan]加上他出现的次数,这也就是方程;哎,读题没读仔细,大忌;;
(6条消息) 2020 Jiangsu Collegiate Programming Contest C D H J 题解_前方77的博客-CSDN博客
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod=1e9+7;
const ll mmod=128;
const ll inf=0x3f3f3f3f;
ll qpow(ll a,ll b){
ll res=1;
while(b){
if(b&1) res=(res*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return res;
}
ll getinv(ll a){return qpow(a,mod-2);}
ll t,n,m,dp[100005],f[100005];
map<string,ll>mp;
int main(){
//freopen("in.txt","r",stdin);
scanf("%lld",&t);
while(t--){
scanf("%lld%lld",&n,&m);
string s,ch,s1;
mp.clear();
for(int i=1;i<=m;i++){
cin>>ch>>s1;
mp[s1]++;
}
for(int i=0;i<=n;i++) dp[i]=0;
for(int i=0;i<=n;i++) f[i]=0;
cin>>s;
s=" "+s;
dp[0]=1;f[0]=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=min(5,i);j++){
string st=s.substr(i-j+1,j);
if(mp[st]>0){
dp[i]=(dp[i]+dp[i-j]*mp[st]%mmod)%mmod;
f[i]=(f[i]+f[i-j]*mp[st]%mod)%mod;//为了看看到最后是不是真的是0,
//因为dp取模128结果可能为0
}
}
//cout<<dp[n]<<" "<<f[n]<<endl;
if(dp[n]==0&&f[n]==0) printf("nonono\n");
else if(dp[n]==1&&f[n]==1) printf("happymorsecode\n");
else printf("puppymousecat %lld\n",dp[n]);
}
return 0;
}